1602a1d70257eb3fcb746d758577f042d8c94f6d9reed@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 8602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com#include "SkScaledImageCache.h" 9d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com#include "SkMipMap.h" 10602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com#include "SkPixelRef.h" 11602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com#include "SkRect.h" 12602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 13e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com// This can be defined by the caller's build system 14e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com//#define SK_USE_DISCARDABLE_SCALEDIMAGECACHE 15e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 16e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com#ifndef SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT 17e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com# define SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT 1024 18e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com#endif 19e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 20602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com#ifndef SK_DEFAULT_IMAGE_CACHE_LIMIT 21602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com #define SK_DEFAULT_IMAGE_CACHE_LIMIT (2 * 1024 * 1024) 22602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com#endif 23602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 247585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.orgstatic inline SkScaledImageCache::ID* rec_to_id(SkScaledImageCache::Rec* rec) { 257585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org return reinterpret_cast<SkScaledImageCache::ID*>(rec); 267585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org} 277585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 287585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.orgstatic inline SkScaledImageCache::Rec* id_to_rec(SkScaledImageCache::ID* id) { 297585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org return reinterpret_cast<SkScaledImageCache::Rec*>(id); 307585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org} 315d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com 32602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com // Implemented from en.wikipedia.org/wiki/MurmurHash. 33602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comstatic uint32_t compute_hash(const uint32_t data[], int count) { 34602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com uint32_t hash = 0; 357f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com 36602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com for (int i = 0; i < count; ++i) { 37602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com uint32_t k = data[i]; 38602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com k *= 0xcc9e2d51; 39602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com k = (k << 15) | (k >> 17); 40602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com k *= 0x1b873593; 417f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com 42602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com hash ^= k; 43602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com hash = (hash << 13) | (hash >> 19); 44602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com hash *= 5; 45602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com hash += 0xe6546b64; 46602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 477f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com 48602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com // hash ^= size; 49602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com hash ^= hash >> 16; 50602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com hash *= 0x85ebca6b; 51602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com hash ^= hash >> 13; 52602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com hash *= 0xc2b2ae35; 53602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com hash ^= hash >> 16; 547f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com 55602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return hash; 56602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 57602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 58d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.comstruct SkScaledImageCache::Key { 597585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org Key(uint32_t genID, 607585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkScalar scaleX, 617585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkScalar scaleY, 627585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkIRect bounds) 637585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org : fGenID(genID) 647585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org , fScaleX(scaleX) 657585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org , fScaleY(scaleY) 667585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org , fBounds(bounds) { 67602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fHash = compute_hash(&fGenID, 7); 68602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 69602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 705d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com bool operator<(const Key& other) const { 71602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com const uint32_t* a = &fGenID; 72602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com const uint32_t* b = &other.fGenID; 73602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com for (int i = 0; i < 7; ++i) { 74602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (a[i] < b[i]) { 75602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return true; 76602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 77602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (a[i] > b[i]) { 78602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return false; 79602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 80602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 81602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return false; 82602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 83602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 845d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com bool operator==(const Key& other) const { 85602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com const uint32_t* a = &fHash; 86602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com const uint32_t* b = &other.fHash; 87602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com for (int i = 0; i < 8; ++i) { 88602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (a[i] != b[i]) { 89602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return false; 90602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 91602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 92602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return true; 93602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 94602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 95602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com uint32_t fHash; 96602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com uint32_t fGenID; 97602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com float fScaleX; 98602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com float fScaleY; 99602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkIRect fBounds; 100602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com}; 101602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 102602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comstruct SkScaledImageCache::Rec { 103602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com Rec(const Key& key, const SkBitmap& bm) : fKey(key), fBitmap(bm) { 104602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fLockCount = 1; 105d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com fMip = NULL; 106602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 1075c561cb8d8151d38c69128345106cbf225033a1askia.committer@gmail.com 108d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com Rec(const Key& key, const SkMipMap* mip) : fKey(key) { 109d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com fLockCount = 1; 110d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com fMip = mip; 111d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com mip->ref(); 112d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com } 1135c561cb8d8151d38c69128345106cbf225033a1askia.committer@gmail.com 114d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com ~Rec() { 115d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com SkSafeUnref(fMip); 116d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com } 1175c561cb8d8151d38c69128345106cbf225033a1askia.committer@gmail.com 11855bd940446506f8409f38271f2e4969e9b4f3991commit-bot@chromium.org static const Key& GetKey(const Rec& rec) { return rec.fKey; } 11955bd940446506f8409f38271f2e4969e9b4f3991commit-bot@chromium.org static uint32_t Hash(const Key& key) { return key.fHash; } 12055bd940446506f8409f38271f2e4969e9b4f3991commit-bot@chromium.org 121602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com size_t bytesUsed() const { 122d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com return fMip ? fMip->getSize() : fBitmap.getSize(); 123602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 124602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 125602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com Rec* fNext; 126602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com Rec* fPrev; 127602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 128602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com // this guy wants to be 64bit aligned 129602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com Key fKey; 130602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 131602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com int32_t fLockCount; 1325c561cb8d8151d38c69128345106cbf225033a1askia.committer@gmail.com 133d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com // we use either fBitmap or fMip, but not both 134602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkBitmap fBitmap; 135d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com const SkMipMap* fMip; 136602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com}; 137602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 1385d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com#include "SkTDynamicHash.h" 1395d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com 14055bd940446506f8409f38271f2e4969e9b4f3991commit-bot@chromium.orgclass SkScaledImageCache::Hash : 14155bd940446506f8409f38271f2e4969e9b4f3991commit-bot@chromium.org public SkTDynamicHash<SkScaledImageCache::Rec, SkScaledImageCache::Key> {}; 142158f64626f8dae7e8437744184860d0110b88609commit-bot@chromium.org 1435d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com 1445d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com/////////////////////////////////////////////////////////////////////////////// 1455d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com 146b8d17fef261eb70305105dddc4089aa744accfcereed@google.com// experimental hash to speed things up 147ea348cb4352cfa09fb060854057dc89ae102a976reed@google.com#define USE_HASH 1485d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com 1497585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org#if !defined(USE_HASH) 1507585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.orgstatic inline SkScaledImageCache::Rec* find_rec_in_list( 1517585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkScaledImageCache::Rec* head, const Key & key) { 1527585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkScaledImageCache::Rec* rec = head; 1537585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org while ((rec != NULL) && (rec->fKey != key)) { 1547585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org rec = rec->fNext; 1557585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org } 1567585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org return rec; 1577585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org} 1587585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org#endif 1597585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 160e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comvoid SkScaledImageCache::init() { 161602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fHead = NULL; 162602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fTail = NULL; 1635d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com#ifdef USE_HASH 1645d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com fHash = new Hash; 1655d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com#else 1665d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com fHash = NULL; 1675d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com#endif 1684e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger fTotalBytesUsed = 0; 169602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fCount = 0; 1704e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger fSingleAllocationByteLimit = 0; 171e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com fAllocator = NULL; 172e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 173e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com // One of these should be explicit set by the caller after we return. 1744e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger fTotalByteLimit = 0; 175e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com fDiscardableFactory = NULL; 176e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com} 177e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 178e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com#include "SkDiscardableMemory.h" 179e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 180e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comclass SkOneShotDiscardablePixelRef : public SkPixelRef { 181e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.compublic: 182227c24673196f5f06bee85e7e9aa067be90e1359commit-bot@chromium.org SK_DECLARE_INST_COUNT(SkOneShotDiscardablePixelRef) 183e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com // Ownership of the discardablememory is transfered to the pixelref 184e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkOneShotDiscardablePixelRef(const SkImageInfo&, SkDiscardableMemory*, size_t rowBytes); 185e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com ~SkOneShotDiscardablePixelRef(); 186e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 187e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SK_DECLARE_UNFLATTENABLE_OBJECT() 188e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 189e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comprotected: 190d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE; 191e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com virtual void onUnlockPixels() SK_OVERRIDE; 192e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE; 193e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 194e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comprivate: 195e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkDiscardableMemory* fDM; 196e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com size_t fRB; 197e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com bool fFirstTime; 198e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 199e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com typedef SkPixelRef INHERITED; 200e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com}; 201e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 202e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comSkOneShotDiscardablePixelRef::SkOneShotDiscardablePixelRef(const SkImageInfo& info, 203e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkDiscardableMemory* dm, 204e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com size_t rowBytes) 205e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com : INHERITED(info) 206e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com , fDM(dm) 207e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com , fRB(rowBytes) 208e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com{ 209e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkASSERT(dm->data()); 210e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com fFirstTime = true; 211e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com} 212e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 213e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comSkOneShotDiscardablePixelRef::~SkOneShotDiscardablePixelRef() { 214e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkDELETE(fDM); 215e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com} 216e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 217d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.combool SkOneShotDiscardablePixelRef::onNewLockPixels(LockRec* rec) { 218e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com if (fFirstTime) { 219e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com // we're already locked 220c83a91f4721739f05f9df51d496d50b5d028b132reed@google.com SkASSERT(fDM->data()); 221e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com fFirstTime = false; 222d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com goto SUCCESS; 223e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com } 224281713e4d4d77e086a0053351da6f7358d3cf4b6commit-bot@chromium.org 225fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com // A previous call to onUnlock may have deleted our DM, so check for that 226fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com if (NULL == fDM) { 227d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com return false; 228fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com } 229fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com 230fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com if (!fDM->lock()) { 231fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com // since it failed, we delete it now, to free-up the resource 232fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com delete fDM; 233fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com fDM = NULL; 234d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com return false; 235fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com } 236d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com 237d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.comSUCCESS: 238d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com rec->fPixels = fDM->data(); 239d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com rec->fColorTable = NULL; 240d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com rec->fRowBytes = fRB; 241d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com return true; 242e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com} 243e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 244e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comvoid SkOneShotDiscardablePixelRef::onUnlockPixels() { 245e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkASSERT(!fFirstTime); 246c83a91f4721739f05f9df51d496d50b5d028b132reed@google.com fDM->unlock(); 247e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com} 248e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 249e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comsize_t SkOneShotDiscardablePixelRef::getAllocatedSizeInBytes() const { 250d0419b1fe781ed21d4aa0dc80df6b3e79ed37e46reed@google.com return this->info().getSafeSize(fRB); 251e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com} 252e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 253e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comclass SkScaledImageCacheDiscardableAllocator : public SkBitmap::Allocator { 254e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.compublic: 255e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkScaledImageCacheDiscardableAllocator( 256e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkScaledImageCache::DiscardableFactory factory) { 257e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkASSERT(factory); 258e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com fFactory = factory; 259e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com } 260e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 261e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com virtual bool allocPixelRef(SkBitmap*, SkColorTable*) SK_OVERRIDE; 262cf0803b46f60d9fcb5ad9a376b638c4c32b655deskia.committer@gmail.com 263e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comprivate: 264e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkScaledImageCache::DiscardableFactory fFactory; 265e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com}; 266e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 267e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.combool SkScaledImageCacheDiscardableAllocator::allocPixelRef(SkBitmap* bitmap, 268e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkColorTable* ctable) { 269e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com size_t size = bitmap->getSize(); 2704e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger uint64_t size64 = bitmap->computeSize64(); 2714e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger if (0 == size || size64 > (uint64_t)size) { 272e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com return false; 273e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com } 274e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 275e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkDiscardableMemory* dm = fFactory(size); 276e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com if (NULL == dm) { 277e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com return false; 278e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com } 279e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 280900ecf2f1579d42c9d2959831787af0346320f86reed@google.com // can we relax this? 28128fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org if (kN32_SkColorType != bitmap->colorType()) { 282e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com return false; 283e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com } 284e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 285900ecf2f1579d42c9d2959831787af0346320f86reed@google.com SkImageInfo info = bitmap->info(); 286e13af711d4ff9031c9ed3054a4c33a56a0c62e1fcommit-bot@chromium.org bitmap->setPixelRef(SkNEW_ARGS(SkOneShotDiscardablePixelRef, 287e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com (info, dm, bitmap->rowBytes())))->unref(); 288e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com bitmap->lockPixels(); 289e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com return bitmap->readyToDraw(); 290e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com} 291e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 292e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comSkScaledImageCache::SkScaledImageCache(DiscardableFactory factory) { 293e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com this->init(); 294e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com fDiscardableFactory = factory; 295e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 296e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com fAllocator = SkNEW_ARGS(SkScaledImageCacheDiscardableAllocator, (factory)); 297e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com} 298e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 299e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comSkScaledImageCache::SkScaledImageCache(size_t byteLimit) { 300e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com this->init(); 3014e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger fTotalByteLimit = byteLimit; 302602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 303602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 304602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comSkScaledImageCache::~SkScaledImageCache() { 305e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkSafeUnref(fAllocator); 306e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 307602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com Rec* rec = fHead; 308602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com while (rec) { 309602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com Rec* next = rec->fNext; 310602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkDELETE(rec); 311602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com rec = next; 312602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 3135d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com delete fHash; 314602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 315602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 3167585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////// 3177585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 318d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com 3197585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.orgSkScaledImageCache::Rec* SkScaledImageCache::findAndLock(uint32_t genID, 320602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkScalar scaleX, 3217585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkScalar scaleY, 3227585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org const SkIRect& bounds) { 323d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com const Key key(genID, scaleX, scaleY, bounds); 324d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com return this->findAndLock(key); 325d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com} 326d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com 327d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com/** 328d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com This private method is the fully general record finder. All other 329d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com record finders should call this function or the one above. */ 330d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.comSkScaledImageCache::Rec* SkScaledImageCache::findAndLock(const SkScaledImageCache::Key& key) { 331d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com if (key.fBounds.isEmpty()) { 332602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return NULL; 333602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 3345d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com#ifdef USE_HASH 3355d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com Rec* rec = fHash->find(key); 3365d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com#else 3377585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org Rec* rec = find_rec_in_list(fHead, key); 3385d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com#endif 3395d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com if (rec) { 3405d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com this->moveToHead(rec); // for our LRU 3415d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com rec->fLockCount += 1; 3425d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com } 3435d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com return rec; 344602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 345602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 3467585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org/** 3477585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org This function finds the bounds of the bitmap *within its pixelRef*. 3487585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org If the bitmap lacks a pixelRef, it will return an empty rect, since 3497585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org that doesn't make sense. This may be a useful enough function that 3507585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org it should be somewhere else (in SkBitmap?). */ 3517585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.orgstatic SkIRect get_bounds_from_bitmap(const SkBitmap& bm) { 3527585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org if (!(bm.pixelRef())) { 3537585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org return SkIRect::MakeEmpty(); 3547585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org } 355672588b684d484dce6ae251e9e163e4a46924322reed@google.com SkIPoint origin = bm.pixelRefOrigin(); 356672588b684d484dce6ae251e9e163e4a46924322reed@google.com return SkIRect::MakeXYWH(origin.fX, origin.fY, bm.width(), bm.height()); 3577585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org} 3587585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 3597585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 3607585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.orgSkScaledImageCache::ID* SkScaledImageCache::findAndLock(uint32_t genID, 3617585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org int32_t width, 3627585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org int32_t height, 3637585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkBitmap* bitmap) { 3647585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org Rec* rec = this->findAndLock(genID, SK_Scalar1, SK_Scalar1, 3657585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkIRect::MakeWH(width, height)); 3667585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org if (rec) { 3677585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkASSERT(NULL == rec->fMip); 3687585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkASSERT(rec->fBitmap.pixelRef()); 3697585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org *bitmap = rec->fBitmap; 3707585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org } 3717585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org return rec_to_id(rec); 3727585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org} 3737585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 374d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.comSkScaledImageCache::ID* SkScaledImageCache::findAndLock(const SkBitmap& orig, 375d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com SkScalar scaleX, 376d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com SkScalar scaleY, 377d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com SkBitmap* scaled) { 378d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com if (0 == scaleX || 0 == scaleY) { 379d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com // degenerate, and the key we use for mipmaps 380d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com return NULL; 381d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com } 3827585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org Rec* rec = this->findAndLock(orig.getGenerationID(), scaleX, 3837585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org scaleY, get_bounds_from_bitmap(orig)); 384d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com if (rec) { 385d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com SkASSERT(NULL == rec->fMip); 386d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com SkASSERT(rec->fBitmap.pixelRef()); 387d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com *scaled = rec->fBitmap; 388d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com } 3897585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org return rec_to_id(rec); 390d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com} 391d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com 392d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.comSkScaledImageCache::ID* SkScaledImageCache::findAndLockMip(const SkBitmap& orig, 393d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com SkMipMap const ** mip) { 394b77f0f4ae560e97cc4cd2758752d955549017c3cskia.committer@gmail.com Rec* rec = this->findAndLock(orig.getGenerationID(), 0, 0, 3957585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org get_bounds_from_bitmap(orig)); 396d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com if (rec) { 397d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com SkASSERT(rec->fMip); 398d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com SkASSERT(NULL == rec->fBitmap.pixelRef()); 399d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com *mip = rec->fMip; 400d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com } 4017585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org return rec_to_id(rec); 4027585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org} 4037585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 4047585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 4057585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////// 4067585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org/** 4077585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org This private method is the fully general record adder. All other 4087585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org record adders should call this funtion. */ 409d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.comSkScaledImageCache::ID* SkScaledImageCache::addAndLock(SkScaledImageCache::Rec* rec) { 4107585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkASSERT(rec); 411d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com // See if we already have this key (racy inserts, etc.) 412d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com Rec* existing = this->findAndLock(rec->fKey); 4135db04dfad7dae105adcb82caf013f4775bfe1257robertphillips@google.com if (NULL != existing) { 4145db04dfad7dae105adcb82caf013f4775bfe1257robertphillips@google.com // Since we already have a matching entry, just delete the new one and return. 4155db04dfad7dae105adcb82caf013f4775bfe1257robertphillips@google.com // Call sites cannot assume the passed in object will live past this call. 4165e4112b33aeecbb773ed4c8e33994dec14becb84commit-bot@chromium.org existing->fBitmap = rec->fBitmap; 4175db04dfad7dae105adcb82caf013f4775bfe1257robertphillips@google.com SkDELETE(rec); 418d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com return rec_to_id(existing); 419d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com } 420d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com 4217585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org this->addToHead(rec); 4227585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkASSERT(1 == rec->fLockCount); 4237585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org#ifdef USE_HASH 4247585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkASSERT(fHash); 4257585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org fHash->add(rec); 4267585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org#endif 4277585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org // We may (now) be overbudget, so see if we need to purge something. 4287585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org this->purgeAsNeeded(); 429d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com return rec_to_id(rec); 4307585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org} 4317585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 4327585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.orgSkScaledImageCache::ID* SkScaledImageCache::addAndLock(uint32_t genID, 4337585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org int32_t width, 4347585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org int32_t height, 4357585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org const SkBitmap& bitmap) { 4367585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org Key key(genID, SK_Scalar1, SK_Scalar1, SkIRect::MakeWH(width, height)); 4377585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org Rec* rec = SkNEW_ARGS(Rec, (key, bitmap)); 438d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com return this->addAndLock(rec); 439d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com} 440d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com 441602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comSkScaledImageCache::ID* SkScaledImageCache::addAndLock(const SkBitmap& orig, 442602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkScalar scaleX, 443602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkScalar scaleY, 444602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com const SkBitmap& scaled) { 445d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com if (0 == scaleX || 0 == scaleY) { 446d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com // degenerate, and the key we use for mipmaps 447d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com return NULL; 448d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com } 4497585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkIRect bounds = get_bounds_from_bitmap(orig); 4507585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org if (bounds.isEmpty()) { 451602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return NULL; 452602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 4537585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org Key key(orig.getGenerationID(), scaleX, scaleY, bounds); 454602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com Rec* rec = SkNEW_ARGS(Rec, (key, scaled)); 455d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com return this->addAndLock(rec); 456d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com} 457602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 458d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.comSkScaledImageCache::ID* SkScaledImageCache::addAndLockMip(const SkBitmap& orig, 459d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com const SkMipMap* mip) { 4607585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkIRect bounds = get_bounds_from_bitmap(orig); 4617585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org if (bounds.isEmpty()) { 462d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com return NULL; 463d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com } 4647585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org Key key(orig.getGenerationID(), 0, 0, bounds); 465d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com Rec* rec = SkNEW_ARGS(Rec, (key, mip)); 466d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com return this->addAndLock(rec); 467602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 468602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 469602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comvoid SkScaledImageCache::unlock(SkScaledImageCache::ID* id) { 470602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(id); 471602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 472602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com#ifdef SK_DEBUG 473602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com { 474602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com bool found = false; 475602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com Rec* rec = fHead; 476602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com while (rec != NULL) { 4777585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org if (rec == id_to_rec(id)) { 478602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com found = true; 479602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com break; 480602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 481602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com rec = rec->fNext; 482602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 483602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(found); 484602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 485602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com#endif 4867585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org Rec* rec = id_to_rec(id); 487602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(rec->fLockCount > 0); 488602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com rec->fLockCount -= 1; 489602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 490602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com // we may have been over-budget, but now have released something, so check 491602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com // if we should purge. 492602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (0 == rec->fLockCount) { 493602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com this->purgeAsNeeded(); 494602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 495602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 496602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 497602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comvoid SkScaledImageCache::purgeAsNeeded() { 498e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com size_t byteLimit; 499e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com int countLimit; 500e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 501e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com if (fDiscardableFactory) { 502e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com countLimit = SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT; 503e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com byteLimit = SK_MaxU32; // no limit based on bytes 504e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com } else { 505e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com countLimit = SK_MaxS32; // no limit based on count 5064e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger byteLimit = fTotalByteLimit; 507e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com } 5087f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com 5094e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger size_t bytesUsed = fTotalBytesUsed; 510e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com int countUsed = fCount; 511cf0803b46f60d9fcb5ad9a376b638c4c32b655deskia.committer@gmail.com 512602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com Rec* rec = fTail; 513602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com while (rec) { 514e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com if (bytesUsed < byteLimit && countUsed < countLimit) { 515602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com break; 516602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 517e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 518602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com Rec* prev = rec->fPrev; 519602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (0 == rec->fLockCount) { 520602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com size_t used = rec->bytesUsed(); 521602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(used <= bytesUsed); 522602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com this->detach(rec); 5235d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com#ifdef USE_HASH 5245d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com fHash->remove(rec->fKey); 5255d1e5589fe446a59372debd8c7221170e21ec2b8reed@google.com#endif 526956b310f13c7412c035406c658ff16ca85eac656skia.committer@gmail.com 527602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkDELETE(rec); 528e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 529e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com bytesUsed -= used; 530e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com countUsed -= 1; 531602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 532602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com rec = prev; 533602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 534e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 5354e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger fTotalBytesUsed = bytesUsed; 536e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com fCount = countUsed; 537602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 538602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 5394e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkScaledImageCache::setTotalByteLimit(size_t newLimit) { 5404e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger size_t prevLimit = fTotalByteLimit; 5414e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger fTotalByteLimit = newLimit; 542602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (newLimit < prevLimit) { 543602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com this->purgeAsNeeded(); 544602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 545602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return prevLimit; 546602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 547602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 548602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com/////////////////////////////////////////////////////////////////////////////// 549602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 550602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comvoid SkScaledImageCache::detach(Rec* rec) { 551602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com Rec* prev = rec->fPrev; 552602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com Rec* next = rec->fNext; 5537f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com 554602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (!prev) { 555602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(fHead == rec); 556602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fHead = next; 557602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } else { 558602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com prev->fNext = next; 559602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 5607f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com 561602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (!next) { 562602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fTail = prev; 563602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } else { 564602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com next->fPrev = prev; 565602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 5667f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com 567602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com rec->fNext = rec->fPrev = NULL; 568602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 569602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 570602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comvoid SkScaledImageCache::moveToHead(Rec* rec) { 571602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (fHead == rec) { 572602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return; 573602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 574602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 575602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(fHead); 576602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(fTail); 577602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 578602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com this->validate(); 579602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 580602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com this->detach(rec); 581602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 582602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fHead->fPrev = rec; 583602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com rec->fNext = fHead; 584602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fHead = rec; 5857f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com 586602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com this->validate(); 587602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 588602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 589602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comvoid SkScaledImageCache::addToHead(Rec* rec) { 590602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com this->validate(); 591602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 592602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com rec->fPrev = NULL; 593602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com rec->fNext = fHead; 594602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (fHead) { 595602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fHead->fPrev = rec; 596602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 597602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fHead = rec; 598602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (!fTail) { 599602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fTail = rec; 600602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 6014e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger fTotalBytesUsed += rec->bytesUsed(); 602602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com fCount += 1; 603602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 604602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com this->validate(); 605602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 606602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 607fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com/////////////////////////////////////////////////////////////////////////////// 608fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com 609602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com#ifdef SK_DEBUG 610602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comvoid SkScaledImageCache::validate() const { 611602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (NULL == fHead) { 612602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(NULL == fTail); 6134e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger SkASSERT(0 == fTotalBytesUsed); 614602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return; 615602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 616602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 617602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com if (fHead == fTail) { 618602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(NULL == fHead->fPrev); 619602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(NULL == fHead->fNext); 6204e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger SkASSERT(fHead->bytesUsed() == fTotalBytesUsed); 621602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return; 622602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 623602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 624602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(NULL == fHead->fPrev); 625602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(NULL != fHead->fNext); 626602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(NULL == fTail->fNext); 627602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(NULL != fTail->fPrev); 628602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 629602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com size_t used = 0; 630602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com int count = 0; 631602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com const Rec* rec = fHead; 632602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com while (rec) { 633602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com count += 1; 634602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com used += rec->bytesUsed(); 6354e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger SkASSERT(used <= fTotalBytesUsed); 636602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com rec = rec->fNext; 637602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 638602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(fCount == count); 639602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 640602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com rec = fTail; 641602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com while (rec) { 642602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(count > 0); 643602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com count -= 1; 644602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(used >= rec->bytesUsed()); 645602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com used -= rec->bytesUsed(); 646602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com rec = rec->fPrev; 647602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com } 6487f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com 649602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(0 == count); 650602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkASSERT(0 == used); 651602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 652602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com#endif 653602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 654fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.comvoid SkScaledImageCache::dump() const { 655fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com this->validate(); 656fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com 657fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com const Rec* rec = fHead; 658fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com int locked = 0; 659fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com while (rec) { 660fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com locked += rec->fLockCount > 0; 661fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com rec = rec->fNext; 662fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com } 663fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com 664fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com SkDebugf("SkScaledImageCache: count=%d bytes=%d locked=%d %s\n", 6654e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger fCount, fTotalBytesUsed, locked, 666fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com fDiscardableFactory ? "discardable" : "malloc"); 667fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com} 668fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com 6694e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkScaledImageCache::setSingleAllocationByteLimit(size_t newLimit) { 6704e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger size_t oldLimit = fSingleAllocationByteLimit; 6714e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger fSingleAllocationByteLimit = newLimit; 6724e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger return oldLimit; 6734e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger} 6744e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger 6754e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkScaledImageCache::getSingleAllocationByteLimit() const { 6764e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger return fSingleAllocationByteLimit; 6774e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger} 6784e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger 679602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com/////////////////////////////////////////////////////////////////////////////// 680602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 681602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com#include "SkThread.h" 682602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 683be19dbe488e21cd9dc8c7adfbbd13602ee67a326reed@google.comSK_DECLARE_STATIC_MUTEX(gMutex); 684709ca75f032d7c60eb53c5840524a875a3a6cdb1commit-bot@chromium.orgstatic SkScaledImageCache* gScaledImageCache = NULL; 68577ec7a6f44ccfdacc9c3422516f09720ca17f9e2mtkleinstatic void cleanup_gScaledImageCache() { 68677ec7a6f44ccfdacc9c3422516f09720ca17f9e2mtklein // We'll clean this up in our own tests, but disable for clients. 68777ec7a6f44ccfdacc9c3422516f09720ca17f9e2mtklein // Chrome seems to have funky multi-process things going on in unit tests that 68877ec7a6f44ccfdacc9c3422516f09720ca17f9e2mtklein // makes this unsafe to delete when the main process atexit()s. 68977ec7a6f44ccfdacc9c3422516f09720ca17f9e2mtklein // SkLazyPtr does the same sort of thing. 69077ec7a6f44ccfdacc9c3422516f09720ca17f9e2mtklein#if SK_DEVELOPER 69177ec7a6f44ccfdacc9c3422516f09720ca17f9e2mtklein SkDELETE(gScaledImageCache); 69277ec7a6f44ccfdacc9c3422516f09720ca17f9e2mtklein#endif 69377ec7a6f44ccfdacc9c3422516f09720ca17f9e2mtklein} 694602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 69560c8d24f84105dd341e36a7fc97e25f88ceef309commit-bot@chromium.org/** Must hold gMutex when calling. */ 69660c8d24f84105dd341e36a7fc97e25f88ceef309commit-bot@chromium.orgstatic SkScaledImageCache* get_cache() { 69760c8d24f84105dd341e36a7fc97e25f88ceef309commit-bot@chromium.org // gMutex is always held when this is called, so we don't need to be fancy in here. 698b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein gMutex.assertHeld(); 69960c8d24f84105dd341e36a7fc97e25f88ceef309commit-bot@chromium.org if (NULL == gScaledImageCache) { 700e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com#ifdef SK_USE_DISCARDABLE_SCALEDIMAGECACHE 70160c8d24f84105dd341e36a7fc97e25f88ceef309commit-bot@chromium.org gScaledImageCache = SkNEW_ARGS(SkScaledImageCache, (SkDiscardableMemory::Create)); 702e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com#else 70360c8d24f84105dd341e36a7fc97e25f88ceef309commit-bot@chromium.org gScaledImageCache = SkNEW_ARGS(SkScaledImageCache, (SK_DEFAULT_IMAGE_CACHE_LIMIT)); 704e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com#endif 70560c8d24f84105dd341e36a7fc97e25f88ceef309commit-bot@chromium.org atexit(cleanup_gScaledImageCache); 70660c8d24f84105dd341e36a7fc97e25f88ceef309commit-bot@chromium.org } 707709ca75f032d7c60eb53c5840524a875a3a6cdb1commit-bot@chromium.org return gScaledImageCache; 708602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 709602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 7107585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 7117585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.orgSkScaledImageCache::ID* SkScaledImageCache::FindAndLock( 7127585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org uint32_t pixelGenerationID, 7137585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org int32_t width, 7147585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org int32_t height, 7157585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkBitmap* scaled) { 7167585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkAutoMutexAcquire am(gMutex); 7177585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org return get_cache()->findAndLock(pixelGenerationID, width, height, scaled); 7187585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org} 7197585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 7207585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.orgSkScaledImageCache::ID* SkScaledImageCache::AddAndLock( 7217585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org uint32_t pixelGenerationID, 7227585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org int32_t width, 7237585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org int32_t height, 7247585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org const SkBitmap& scaled) { 7257585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org SkAutoMutexAcquire am(gMutex); 7267585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org return get_cache()->addAndLock(pixelGenerationID, width, height, scaled); 7277585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org} 7287585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 7297585479202f1fe0b6a0a9dcd27697b56154706f4commit-bot@chromium.org 730602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comSkScaledImageCache::ID* SkScaledImageCache::FindAndLock(const SkBitmap& orig, 731602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkScalar scaleX, 732602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkScalar scaleY, 733602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkBitmap* scaled) { 734602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkAutoMutexAcquire am(gMutex); 735602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return get_cache()->findAndLock(orig, scaleX, scaleY, scaled); 736602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 737602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 738d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.comSkScaledImageCache::ID* SkScaledImageCache::FindAndLockMip(const SkBitmap& orig, 739d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com SkMipMap const ** mip) { 740d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com SkAutoMutexAcquire am(gMutex); 741d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com return get_cache()->findAndLockMip(orig, mip); 742d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com} 743d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com 744602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comSkScaledImageCache::ID* SkScaledImageCache::AddAndLock(const SkBitmap& orig, 745602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkScalar scaleX, 746602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkScalar scaleY, 747602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com const SkBitmap& scaled) { 748602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkAutoMutexAcquire am(gMutex); 749602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com return get_cache()->addAndLock(orig, scaleX, scaleY, scaled); 750602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 751602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 752d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.comSkScaledImageCache::ID* SkScaledImageCache::AddAndLockMip(const SkBitmap& orig, 753d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com const SkMipMap* mip) { 754d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com SkAutoMutexAcquire am(gMutex); 755d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com return get_cache()->addAndLockMip(orig, mip); 756d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com} 757d94697c21ae479df4190a1afbf08d85ce244a4efreed@google.com 758602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.comvoid SkScaledImageCache::Unlock(SkScaledImageCache::ID* id) { 759602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkAutoMutexAcquire am(gMutex); 760fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com get_cache()->unlock(id); 761fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com 762fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com// get_cache()->dump(); 763602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 764602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 7654e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkScaledImageCache::GetTotalBytesUsed() { 766602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkAutoMutexAcquire am(gMutex); 7674e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger return get_cache()->getTotalBytesUsed(); 768602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 769602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 7704e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkScaledImageCache::GetTotalByteLimit() { 771602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkAutoMutexAcquire am(gMutex); 7724e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger return get_cache()->getTotalByteLimit(); 773602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 774602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 7754e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkScaledImageCache::SetTotalByteLimit(size_t newLimit) { 776602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com SkAutoMutexAcquire am(gMutex); 7774e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger return get_cache()->setTotalByteLimit(newLimit); 778602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 779602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 780e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.comSkBitmap::Allocator* SkScaledImageCache::GetAllocator() { 781e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com SkAutoMutexAcquire am(gMutex); 782e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com return get_cache()->allocator(); 783e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com} 784e4eb122a61d7c29f1dd979a41d90524fd249db3freed@google.com 785fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.comvoid SkScaledImageCache::Dump() { 786fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com SkAutoMutexAcquire am(gMutex); 787fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com get_cache()->dump(); 788fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com} 789fa7fd80ec36103351c32a7a1f235a6095110c39creed@google.com 7904e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkScaledImageCache::SetSingleAllocationByteLimit(size_t size) { 7914e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger SkAutoMutexAcquire am(gMutex); 7924e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger return get_cache()->setSingleAllocationByteLimit(size); 7934e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger} 7944e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger 7954e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkScaledImageCache::GetSingleAllocationByteLimit() { 7964e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger SkAutoMutexAcquire am(gMutex); 7974e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger return get_cache()->getSingleAllocationByteLimit(); 7984e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger} 7994e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger 800602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com/////////////////////////////////////////////////////////////////////////////// 801602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 802602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com#include "SkGraphics.h" 803602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 8044e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkGraphics::GetImageCacheTotalBytesUsed() { 8054e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger return SkScaledImageCache::GetTotalBytesUsed(); 8064e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger} 8074e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger 8084e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkGraphics::GetImageCacheTotalByteLimit() { 8094e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger return SkScaledImageCache::GetTotalByteLimit(); 810602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 811602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 8124e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkGraphics::SetImageCacheTotalByteLimit(size_t newLimit) { 8134e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger return SkScaledImageCache::SetTotalByteLimit(newLimit); 814602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 815602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com 8164e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkGraphics::GetImageCacheSingleAllocationByteLimit() { 8174e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger return SkScaledImageCache::GetSingleAllocationByteLimit(); 818602a1d70257eb3fcb746d758577f042d8c94f6d9reed@google.com} 8194e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger 8204e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenbergersize_t SkGraphics::SetImageCacheSingleAllocationByteLimit(size_t newLimit) { 8214e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger return SkScaledImageCache::SetSingleAllocationByteLimit(newLimit); 8224e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger} 8234e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger 824