1ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 10ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 1150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com#ifndef GrResourceCache_DEFINED 1250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com#define GrResourceCache_DEFINED 13ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 145955202c805c7ef1448103cbf666972ea9d1ded1robertphillips@google.com#include "GrConfig.h" 15ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrTypes.h" 16bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org#include "GrTMultiMap.h" 170797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com#include "GrBinHashKey.h" 1850a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org#include "SkMessageBus.h" 1942619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com#include "SkTInternalLList.h" 20ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 21089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.orgclass GrCacheable; 2211c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.orgclass GrResourceCache; 23089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.orgclass GrResourceCacheEntry; 24ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2550398bf7f1953e640e5529616e710cf540799731bsalomon@google.comclass GrResourceKey { 26ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.compublic: 270797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com static GrCacheID::Domain ScratchDomain() { 280797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com static const GrCacheID::Domain gDomain = GrCacheID::GenerateDomain(); 290797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com return gDomain; 3050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com } 3150398bf7f1953e640e5529616e710cf540799731bsalomon@google.com 32089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org /** Uniquely identifies the GrCacheable subclass in the key to avoid collisions 330797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com across resource types. */ 340797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com typedef uint8_t ResourceType; 350797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 36089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org /** Flags set by the GrCacheable subclass. */ 370797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com typedef uint8_t ResourceFlags; 380797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 390797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com /** Generate a unique ResourceType */ 400797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com static ResourceType GenerateResourceType(); 410797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 420797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com /** Creates a key for resource */ 430797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com GrResourceKey(const GrCacheID& id, ResourceType type, ResourceFlags flags) { 440797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com this->init(id.getDomain(), id.getKey(), type, flags); 450797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com }; 46ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 470b6ad2297fbf43466950690102c1c9c150f2a972bsalomon@google.com GrResourceKey(const GrResourceKey& src) { 480797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com fKey = src.fKey; 49ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 50ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 510797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com GrResourceKey() { 52d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com fKey.reset(); 530797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com } 54ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 550797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com void reset(const GrCacheID& id, ResourceType type, ResourceFlags flags) { 560797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com this->init(id.getDomain(), id.getKey(), type, flags); 57ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 5801804b44f9e4c468ef94aa3fe609a0a1b65fde3dreed@google.com 59bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org uint32_t getHash() const { 60bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org return fKey.getHash(); 61ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 62fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com 630797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com bool isScratch() const { 640797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com return ScratchDomain() == 65d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com *reinterpret_cast<const GrCacheID::Domain*>(fKey.getData() + 660797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com kCacheIDDomainOffset); 67ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 684b86e3428b115202e82d49a0914ea8ab6dc25940bsalomon@google.com 690797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com ResourceType getResourceType() const { 70d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com return *reinterpret_cast<const ResourceType*>(fKey.getData() + 710797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com kResourceTypeOffset); 72ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 734b86e3428b115202e82d49a0914ea8ab6dc25940bsalomon@google.com 740797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com ResourceFlags getResourceFlags() const { 75d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com return *reinterpret_cast<const ResourceFlags*>(fKey.getData() + 760797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com kResourceFlagsOffset); 77ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 780797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com 79d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com bool operator==(const GrResourceKey& other) const { return fKey == other.fKey; } 80ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 810797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.comprivate: 820797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com enum { 830797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com kCacheIDKeyOffset = 0, 840797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com kCacheIDDomainOffset = kCacheIDKeyOffset + sizeof(GrCacheID::Key), 850797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com kResourceTypeOffset = kCacheIDDomainOffset + sizeof(GrCacheID::Domain), 860797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com kResourceFlagsOffset = kResourceTypeOffset + sizeof(ResourceType), 870797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com kPadOffset = kResourceFlagsOffset + sizeof(ResourceFlags), 880797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com kKeySize = SkAlign4(kPadOffset), 890797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com kPadSize = kKeySize - kPadOffset 900797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com }; 914b86e3428b115202e82d49a0914ea8ab6dc25940bsalomon@google.com 920797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com void init(const GrCacheID::Domain domain, 930797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com const GrCacheID::Key& key, 940797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com ResourceType type, 950797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com ResourceFlags flags) { 960797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com union { 970797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com uint8_t fKey8[kKeySize]; 980797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com uint32_t fKey32[kKeySize / 4]; 990797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com } keyData; 1002859eb74f9c87471b2429cd12b84144b97157efbskia.committer@gmail.com 1010797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com uint8_t* k = keyData.fKey8; 1020797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com memcpy(k + kCacheIDKeyOffset, key.fData8, sizeof(GrCacheID::Key)); 1030797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com memcpy(k + kCacheIDDomainOffset, &domain, sizeof(GrCacheID::Domain)); 1040797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com memcpy(k + kResourceTypeOffset, &type, sizeof(ResourceType)); 1050797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com memcpy(k + kResourceFlagsOffset, &flags, sizeof(ResourceFlags)); 1060797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com memset(k + kPadOffset, 0, kPadSize); 107d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com fKey.setKeyData(keyData.fKey32); 1080797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com } 109d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com GrBinHashKey<kKeySize> fKey; 1100797c2cceadd7dfc2e7f9efa30b611d18efcdcddbsalomon@google.com}; 1110b6ad2297fbf43466950690102c1c9c150f2a972bsalomon@google.com 11250a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org// The cache listens for these messages to purge junk resources proactively. 11350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.orgstruct GrResourceInvalidatedMessage { 11450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org GrResourceKey key; 11550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org}; 11650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 117ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/////////////////////////////////////////////////////////////////////////////// 118ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 119089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.orgclass GrResourceCacheEntry { 120ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.compublic: 121089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org GrCacheable* resource() const { return fResource; } 12250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com const GrResourceKey& key() const { return fKey; } 123ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 124089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org static const GrResourceKey& GetKey(const GrResourceCacheEntry& e) { return e.key(); } 125bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org static uint32_t Hash(const GrResourceKey& key) { return key.getHash(); } 126515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 127ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com void validate() const; 128ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#else 129ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com void validate() const {} 130ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 131ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 13211c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org /** 13311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org * Update the cached size for this entry and inform the resource cache that 13411c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org * it has changed. Usually invoked from GrCacheable::didChangeGpuMemorySize, 13511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org * not directly from here. 13611c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org */ 13711c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org void didChangeResourceSize(); 13811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 139ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comprivate: 14011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org GrResourceCacheEntry(GrResourceCache* resourceCache, 14111c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org const GrResourceKey& key, 14211c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org GrCacheable* resource); 143089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org ~GrResourceCacheEntry(); 144ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 14511c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org GrResourceCache* fResourceCache; 14650398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceKey fKey; 147089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org GrCacheable* fResource; 14811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org size_t fCachedSize; 14911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org bool fIsExclusive; 150ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 151bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org // Linked list for the LRU ordering. 152089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrResourceCacheEntry); 153ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 15450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com friend class GrResourceCache; 155ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}; 156ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 157ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/////////////////////////////////////////////////////////////////////////////// 158ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 159ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/** 160089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org * Cache of GrCacheable objects. 161ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * 16250398bf7f1953e640e5529616e710cf540799731bsalomon@google.com * These have a corresponding GrResourceKey, built from 128bits identifying the 163bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org * resource. Multiple resources can map to same GrResourceKey. 164ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * 165ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * The cache stores the entries in a double-linked list, which is its LRU. 166ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * When an entry is "locked" (i.e. given to the caller), it is moved to the 167ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * head of the list. If/when we must purge some of the entries, we walk the 168ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * list backwards from the tail, since those are the least recently used. 169ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * 170bd58febffb103ea830bf027c5a95313548f7ea8ecommit-bot@chromium.org * For fast searches, we maintain a hash map based on the GrResourceKey. 17176202b8dc39652b2832b279fc4cb798a0ea03ed3bsalomon@google.com * 17276202b8dc39652b2832b279fc4cb798a0ea03ed3bsalomon@google.com * It is a goal to make the GrResourceCache the central repository and bookkeeper 173089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org * of all resources. It should replace the linked list of GrGpuObjects that 17476202b8dc39652b2832b279fc4cb798a0ea03ed3bsalomon@google.com * GrGpu uses to call abandon/release. 175ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 17650398bf7f1953e640e5529616e710cf540799731bsalomon@google.comclass GrResourceCache { 177ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.compublic: 17807fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com GrResourceCache(int maxCount, size_t maxBytes); 17950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com ~GrResourceCache(); 180ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 181ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com /** 18207fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com * Return the current resource cache limits. 18307fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com * 184fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * @param maxResource If non-null, returns maximum number of resources 18507fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com * that can be held in the cache. 18607fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com * @param maxBytes If non-null, returns maximum number of bytes of 187e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com * gpu memory that can be held in the cache. 18801804b44f9e4c468ef94aa3fe609a0a1b65fde3dreed@google.com */ 18907fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com void getLimits(int* maxResources, size_t* maxBytes) const; 19001804b44f9e4c468ef94aa3fe609a0a1b65fde3dreed@google.com 19101804b44f9e4c468ef94aa3fe609a0a1b65fde3dreed@google.com /** 19207fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com * Specify the resource cache limits. If the current cache exceeds either 19307fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com * of these, it will be purged (LRU) to keep the cache within these limits. 19401804b44f9e4c468ef94aa3fe609a0a1b65fde3dreed@google.com * 19507fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com * @param maxResources The maximum number of resources that can be held in 19607fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com * the cache. 19707fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com * @param maxBytes The maximum number of bytes of resource memory that 19807fc0d178e20f74a88dd78384f817b53204e625fbsalomon@google.com * can be held in the cache. 19901804b44f9e4c468ef94aa3fe609a0a1b65fde3dreed@google.com */ 200e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com void setLimits(int maxResources, size_t maxResourceBytes); 20101804b44f9e4c468ef94aa3fe609a0a1b65fde3dreed@google.com 20201804b44f9e4c468ef94aa3fe609a0a1b65fde3dreed@google.com /** 203cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org * The callback function used by the cache when it is still over budget 204de2e4e8a6422c7d8b5847f038f5c6360b187f7a2skia.committer@gmail.com * after a purge. The passed in 'data' is the same 'data' handed to 205cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org * setOverbudgetCallback. The callback returns true if some resources 206cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org * have been freed. 207cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org */ 208cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org typedef bool (*PFOverbudgetCB)(void* data); 209cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 210cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org /** 211cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org * Set the callback the cache should use when it is still over budget 212de2e4e8a6422c7d8b5847f038f5c6360b187f7a2skia.committer@gmail.com * after a purge. The 'data' provided here will be passed back to the 2131f3c73825b8a1752abc6b74fbce978a430de6473skia.committer@gmail.com * callback. Note that the cache will attempt to purge any resources newly 214e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com * freed by the callback. 215cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org */ 216cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org void setOverbudgetCallback(PFOverbudgetCB overbudgetCB, void* data) { 217cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org fOverbudgetCB = overbudgetCB; 218cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org fOverbudgetData = data; 219cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org } 220cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 221cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org /** 22205e70247c31ae927074ef27ea9893634a8dda543twiz@google.com * Returns the number of bytes consumed by cached resources. 22305e70247c31ae927074ef27ea9893634a8dda543twiz@google.com */ 22405e70247c31ae927074ef27ea9893634a8dda543twiz@google.com size_t getCachedResourceBytes() const { return fEntryBytes; } 22505e70247c31ae927074ef27ea9893634a8dda543twiz@google.com 226d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org /** 227d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org * Returns the number of cached resources. 228d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org */ 229d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org int getCachedResourceCount() const { return fEntryCount; } 230d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org 231209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com // For a found or added resource to be completely exclusive to the caller 232209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com // both the kNoOtherOwners and kHide flags need to be specified 233209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com enum OwnershipFlags { 234209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com kNoOtherOwners_OwnershipFlag = 0x1, // found/added resource has no other owners 235209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com kHide_OwnershipFlag = 0x2 // found/added resource is hidden from future 'find's 236209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com }; 237209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com 23805e70247c31ae927074ef27ea9893634a8dda543twiz@google.com /** 239a9b0623eac4a473517c15418dbdc1e331ee752d2robertphillips@google.com * Search for an entry with the same Key. If found, return it. 240a9b0623eac4a473517c15418dbdc1e331ee752d2robertphillips@google.com * If not found, return null. 241f3dc199c0b18e35ac8de4075ecbede7a484f1b0dskia.committer@gmail.com * If ownershipFlags includes kNoOtherOwners and a resource is returned 242209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com * then that resource has no other refs to it. 243209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com * If ownershipFlags includes kHide and a resource is returned then that 244209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com * resource will not be returned from future 'find' calls until it is 245209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com * 'freed' (and recycled) or makeNonExclusive is called. 246209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com * For a resource to be completely exclusive to a caller both kNoOtherOwners 247209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com * and kHide must be specified. 248a9b0623eac4a473517c15418dbdc1e331ee752d2robertphillips@google.com */ 249089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org GrCacheable* find(const GrResourceKey& key, 250089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org uint32_t ownershipFlags = 0); 251a9b0623eac4a473517c15418dbdc1e331ee752d2robertphillips@google.com 252a9b0623eac4a473517c15418dbdc1e331ee752d2robertphillips@google.com /** 253f3dc199c0b18e35ac8de4075ecbede7a484f1b0dskia.committer@gmail.com * Add the new resource to the cache (by creating a new cache entry based 254f3dc199c0b18e35ac8de4075ecbede7a484f1b0dskia.committer@gmail.com * on the provided key and resource). 255ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com * 256fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * Ownership of the resource is transferred to the resource cache, 25715c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com * which will unref() it when it is purged or deleted. 258209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com * 259209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com * If ownershipFlags includes kHide, subsequent calls to 'find' will not 260f3dc199c0b18e35ac8de4075ecbede7a484f1b0dskia.committer@gmail.com * return 'resource' until it is 'freed' (and recycled) or makeNonExclusive 261209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com * is called. 262ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 263f3dc199c0b18e35ac8de4075ecbede7a484f1b0dskia.committer@gmail.com void addResource(const GrResourceKey& key, 264089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org GrCacheable* resource, 265209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com uint32_t ownershipFlags = 0); 26601804b44f9e4c468ef94aa3fe609a0a1b65fde3dreed@google.com 267ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com /** 268fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com * Determines if the cache contains an entry matching a key. If a matching 269fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com * entry exists but was detached then it will not be found. 270fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com */ 271e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com bool hasKey(const GrResourceKey& key) const { return NULL != fCache.find(key); } 272fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com 273fb30951cd9346a7a2d36e7d5f81f9e7ee792b669bsalomon@google.com /** 274521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com * Hide 'entry' so that future searches will not find it. Such 275521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com * hidden entries will not be purged. The entry still counts against 276521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com * the cache's budget and should be made non-exclusive when exclusive access 277521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com * is no longer needed. 278ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 279089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org void makeExclusive(GrResourceCacheEntry* entry); 28015c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 281ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com /** 282521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com * Restore 'entry' so that it can be found by future searches. 'entry' 283521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com * will also be purgeable (provided its lock count is now 0.) 284ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 285089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org void makeNonExclusive(GrResourceCacheEntry* entry); 286ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 287ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com /** 28811c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org * Notify the cache that the size of a resource has changed. 28911c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org */ 29011c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org void didIncreaseResourceSize(const GrResourceCacheEntry*, size_t amountInc); 29111c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org void didDecreaseResourceSize(const GrResourceCacheEntry*, size_t amountDec); 29211c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org 29311c6b39cfa24f812ceb115589f51a60a56ef14fecommit-bot@chromium.org /** 294e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com * Remove a resource from the cache and delete it! 295e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com */ 296089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org void deleteResource(GrResourceCacheEntry* entry); 297e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com 298e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com /** 299a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com * Removes every resource in the cache that isn't locked. 300a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com */ 301a292112154f803feb9f5cc002bbfab559f7cb633bsalomon@google.com void purgeAllUnlocked(); 302ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 30350a035ddbb068446645b0978f4c092dec87a1a02robertphillips@google.com /** 30450a035ddbb068446645b0978f4c092dec87a1a02robertphillips@google.com * Allow cache to purge unused resources to obey resource limitations 3059fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.com * Note: this entry point will be hidden (again) once totally ref-driven 306e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com * cache maintenance is implemented. Note that the overbudget callback 307e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com * will be called if the initial purge doesn't get the cache under 308e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com * its budget. 30941d2532931a2e85b56ae112047d57927cb09ef6frobertphillips@google.com * 31041d2532931a2e85b56ae112047d57927cb09ef6frobertphillips@google.com * extraCount and extraBytes are added to the current resource allocation 31141d2532931a2e85b56ae112047d57927cb09ef6frobertphillips@google.com * to make sure enough room is available for future additions (e.g, 31241d2532931a2e85b56ae112047d57927cb09ef6frobertphillips@google.com * 10MB across 10 textures is about to be added). 31350a035ddbb068446645b0978f4c092dec87a1a02robertphillips@google.com */ 31441d2532931a2e85b56ae112047d57927cb09ef6frobertphillips@google.com void purgeAsNeeded(int extraCount = 0, size_t extraBytes = 0); 31550a035ddbb068446645b0978f4c092dec87a1a02robertphillips@google.com 316515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 317ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com void validate() const; 318ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#else 319ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com void validate() const {} 320ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 321ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 3225955202c805c7ef1448103cbf666972ea9d1ded1robertphillips@google.com#if GR_CACHE_STATS 3239fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.com void printStats(); 3245955202c805c7ef1448103cbf666972ea9d1ded1robertphillips@google.com#endif 3255955202c805c7ef1448103cbf666972ea9d1ded1robertphillips@google.com 326ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comprivate: 327209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com enum BudgetBehaviors { 328209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com kAccountFor_BudgetBehavior, 329209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com kIgnore_BudgetBehavior 330209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com }; 331209a1143a1a26935578d45c7f86dc6f9aa2eb1a6robertphillips@google.com 332089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org void internalDetach(GrResourceCacheEntry*, BudgetBehaviors behavior = kAccountFor_BudgetBehavior); 333089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org void attachToHead(GrResourceCacheEntry*, BudgetBehaviors behavior = kAccountFor_BudgetBehavior); 334ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 335089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org void removeInvalidResource(GrResourceCacheEntry* entry); 336521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com 337089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org GrTMultiMap<GrResourceCacheEntry, GrResourceKey> fCache; 338ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 33942619d8df206b0bcd36d952909d972b8961e75debsalomon@google.com // We're an internal doubly linked list 340089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org typedef SkTInternalLList<GrResourceCacheEntry> EntryList; 341e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com EntryList fList; 342521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com 343515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 344521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com // These objects cannot be returned by a search 345e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com EntryList fExclusiveList; 346521eaf8cc73cebebeaf54338c51c22922ac70951robertphillips@google.com#endif 347ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 348ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // our budget, used in purgeAsNeeded() 349e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com int fMaxCount; 350e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com size_t fMaxBytes; 351ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 352ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com // our current stats, related to our budget 3535955202c805c7ef1448103cbf666972ea9d1ded1robertphillips@google.com#if GR_CACHE_STATS 354e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com int fHighWaterEntryCount; 355e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com size_t fHighWaterEntryBytes; 356e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com int fHighWaterClientDetachedCount; 357e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com size_t fHighWaterClientDetachedBytes; 3585f9f2f574fe9b195f5f3e40edeb2e28b673511fdrobertphillips@google.com#endif 3595f9f2f574fe9b195f5f3e40edeb2e28b673511fdrobertphillips@google.com 360e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com int fEntryCount; 361e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com size_t fEntryBytes; 362e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com int fClientDetachedCount; 363e4eaea2d126d58d8ce4034a1ce921404e83fe3f4robertphillips@google.com size_t fClientDetachedBytes; 364386319eebb806f62a60b16826750f364edc94ce5robertphillips@google.com 365a5a1da81d0bed4a65e9d8956e2e2b2b226d4b05dbsalomon@google.com // prevents recursive purging 366cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org bool fPurging; 367cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 368cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org PFOverbudgetCB fOverbudgetCB; 369cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org void* fOverbudgetData; 370cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org 37141d2532931a2e85b56ae112047d57927cb09ef6frobertphillips@google.com void internalPurge(int extraCount, size_t extraBytes); 37215c0fea699b25343fe6f49668a5632866e1a0306robertphillips@google.com 37350a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org // Listen for messages that a resource has been invalidated and purge cached junk proactively. 37450a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org SkMessageBus<GrResourceInvalidatedMessage>::Inbox fInvalidationInbox; 37550a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org void purgeInvalidated(); 37650a3043194cf278a74ff51c33c6cdb52cbe1f8f9commit-bot@chromium.org 377515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 378089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org static size_t countBytes(const SkTInternalLList<GrResourceCacheEntry>& list); 3792ea0a231a82b00e14c57806f6ae4664361d2ed16robertphillips@google.com#endif 380ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}; 381ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 382ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/////////////////////////////////////////////////////////////////////////////// 383ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 384515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG 38550398bf7f1953e640e5529616e710cf540799731bsalomon@google.com class GrAutoResourceCacheValidate { 386ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com public: 38750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAutoResourceCacheValidate(GrResourceCache* cache) : fCache(cache) { 388ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com cache->validate(); 389ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 39050398bf7f1953e640e5529616e710cf540799731bsalomon@google.com ~GrAutoResourceCacheValidate() { 391ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fCache->validate(); 392ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 393ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com private: 39450398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrResourceCache* fCache; 395ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com }; 396ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#else 39750398bf7f1953e640e5529616e710cf540799731bsalomon@google.com class GrAutoResourceCacheValidate { 398ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com public: 39950398bf7f1953e640e5529616e710cf540799731bsalomon@google.com GrAutoResourceCacheValidate(GrResourceCache*) {} 400ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com }; 401ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 402ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 403ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif 404