| OLD | NEW |
| (Empty) |
| 1 #include "SkImageRefPool.h" | |
| 2 #include "SkImageRef.h" | |
| 3 #include "SkThread.h" | |
| 4 | |
| 5 SkImageRefPool::SkImageRefPool() { | |
| 6 fRAMBudget = 0; // means no explicit limit | |
| 7 fRAMUsed = 0; | |
| 8 fCount = 0; | |
| 9 fHead = fTail = NULL; | |
| 10 } | |
| 11 | |
| 12 SkImageRefPool::~SkImageRefPool() { | |
| 13 // SkASSERT(NULL == fHead); | |
| 14 } | |
| 15 | |
| 16 void SkImageRefPool::setRAMBudget(size_t size) { | |
| 17 if (fRAMBudget != size) { | |
| 18 fRAMBudget = size; | |
| 19 this->purgeIfNeeded(); | |
| 20 } | |
| 21 } | |
| 22 | |
| 23 void SkImageRefPool::justAddedPixels(SkImageRef* ref) { | |
| 24 #ifdef DUMP_IMAGEREF_LIFECYCLE | |
| 25 SkDebugf("=== ImagePool: add pixels %s [%d %d %d] bytes=%d heap=%d\n", | |
| 26 ref->fName.c_str(), | |
| 27 ref->fBitmap.width(), ref->fBitmap.height(), | |
| 28 ref->fBitmap.bytesPerPixel(), | |
| 29 ref->fBitmap.getSize(), (int)fRAMUsed); | |
| 30 #endif | |
| 31 fRAMUsed += ref->ramUsed(); | |
| 32 this->purgeIfNeeded(); | |
| 33 } | |
| 34 | |
| 35 void SkImageRefPool::canLosePixels(SkImageRef* ref) { | |
| 36 // the refs near fHead have recently been released (used) | |
| 37 // if we purge, we purge from the tail | |
| 38 this->detach(ref); | |
| 39 this->addToHead(ref); | |
| 40 this->purgeIfNeeded(); | |
| 41 } | |
| 42 | |
| 43 void SkImageRefPool::purgeIfNeeded() { | |
| 44 // do nothing if we have a zero-budget (i.e. unlimited) | |
| 45 if (fRAMBudget != 0) { | |
| 46 this->setRAMUsed(fRAMBudget); | |
| 47 } | |
| 48 } | |
| 49 | |
| 50 void SkImageRefPool::setRAMUsed(size_t limit) { | |
| 51 SkImageRef* ref = fTail; | |
| 52 | |
| 53 while (NULL != ref && fRAMUsed > limit) { | |
| 54 // only purge it if its pixels are unlocked | |
| 55 if (0 == ref->getLockCount() && ref->fBitmap.getPixels()) { | |
| 56 size_t size = ref->ramUsed(); | |
| 57 SkASSERT(size <= fRAMUsed); | |
| 58 fRAMUsed -= size; | |
| 59 | |
| 60 #ifdef DUMP_IMAGEREF_LIFECYCLE | |
| 61 SkDebugf("=== ImagePool: purge %s [%d %d %d] bytes=%d heap=%d\n", | |
| 62 ref->fName.c_str(), | |
| 63 ref->fBitmap.width(), ref->fBitmap.height(), | |
| 64 ref->fBitmap.bytesPerPixel(), | |
| 65 (int)size, (int)fRAMUsed); | |
| 66 #endif | |
| 67 | |
| 68 // remember the bitmap config (don't call reset), | |
| 69 // just clear the pixel memory | |
| 70 ref->fBitmap.setPixels(NULL); | |
| 71 SkASSERT(NULL == ref->fBitmap.getPixels()); | |
| 72 } | |
| 73 ref = ref->fPrev; | |
| 74 } | |
| 75 } | |
| 76 | |
| 77 /////////////////////////////////////////////////////////////////////////////// | |
| 78 | |
| 79 void SkImageRefPool::addToHead(SkImageRef* ref) { | |
| 80 ref->fNext = fHead; | |
| 81 ref->fPrev = NULL; | |
| 82 | |
| 83 if (fHead) { | |
| 84 SkASSERT(NULL == fHead->fPrev); | |
| 85 fHead->fPrev = ref; | |
| 86 } | |
| 87 fHead = ref; | |
| 88 | |
| 89 if (NULL == fTail) { | |
| 90 fTail = ref; | |
| 91 } | |
| 92 fCount += 1; | |
| 93 SkASSERT(computeCount() == fCount); | |
| 94 | |
| 95 fRAMUsed += ref->ramUsed(); | |
| 96 } | |
| 97 | |
| 98 void SkImageRefPool::addToTail(SkImageRef* ref) { | |
| 99 ref->fNext = NULL; | |
| 100 ref->fPrev = fTail; | |
| 101 | |
| 102 if (fTail) { | |
| 103 SkASSERT(NULL == fTail->fNext); | |
| 104 fTail->fNext = ref; | |
| 105 } | |
| 106 fTail = ref; | |
| 107 | |
| 108 if (NULL == fHead) { | |
| 109 fHead = ref; | |
| 110 } | |
| 111 fCount += 1; | |
| 112 SkASSERT(computeCount() == fCount); | |
| 113 | |
| 114 fRAMUsed += ref->ramUsed(); | |
| 115 } | |
| 116 | |
| 117 void SkImageRefPool::detach(SkImageRef* ref) { | |
| 118 SkASSERT(fCount > 0); | |
| 119 | |
| 120 if (fHead == ref) { | |
| 121 fHead = ref->fNext; | |
| 122 } | |
| 123 if (fTail == ref) { | |
| 124 fTail = ref->fPrev; | |
| 125 } | |
| 126 if (ref->fPrev) { | |
| 127 ref->fPrev->fNext = ref->fNext; | |
| 128 } | |
| 129 if (ref->fNext) { | |
| 130 ref->fNext->fPrev = ref->fPrev; | |
| 131 } | |
| 132 | |
| 133 ref->fNext = ref->fPrev = NULL; | |
| 134 | |
| 135 fCount -= 1; | |
| 136 SkASSERT(computeCount() == fCount); | |
| 137 | |
| 138 SkASSERT(fRAMUsed >= ref->ramUsed()); | |
| 139 fRAMUsed -= ref->ramUsed(); | |
| 140 } | |
| 141 | |
| 142 int SkImageRefPool::computeCount() const { | |
| 143 SkImageRef* ref = fHead; | |
| 144 int count = 0; | |
| 145 | |
| 146 while (ref != NULL) { | |
| 147 count += 1; | |
| 148 ref = ref->fNext; | |
| 149 } | |
| 150 | |
| 151 #ifdef SK_DEBUG | |
| 152 ref = fTail; | |
| 153 int count2 = 0; | |
| 154 | |
| 155 while (ref != NULL) { | |
| 156 count2 += 1; | |
| 157 ref = ref->fPrev; | |
| 158 } | |
| 159 SkASSERT(count2 == count); | |
| 160 #endif | |
| 161 | |
| 162 return count; | |
| 163 } | |
| 164 | |
| 165 /////////////////////////////////////////////////////////////////////////////// | |
| 166 | |
| 167 #include "SkStream.h" | |
| 168 | |
| 169 void SkImageRefPool::dump() const { | |
| 170 #if defined(SK_DEBUG) || defined(DUMP_IMAGEREF_LIFECYCLE) | |
| 171 SkDebugf("ImagePool dump: bugdet: %d used: %d count: %d\n", | |
| 172 (int)fRAMBudget, (int)fRAMUsed, fCount); | |
| 173 | |
| 174 SkImageRef* ref = fHead; | |
| 175 | |
| 176 while (ref != NULL) { | |
| 177 SkDebugf(" [%3d %3d %d] ram=%d data=%d locks=%d %s\n", ref->fBitmap.wid
th(), | |
| 178 ref->fBitmap.height(), ref->fBitmap.config(), | |
| 179 ref->ramUsed(), (int)ref->fStream->getLength(), | |
| 180 ref->getLockCount(), ref->fName.c_str()); | |
| 181 | |
| 182 ref = ref->fNext; | |
| 183 } | |
| 184 #endif | |
| 185 } | |
| 186 | |
| OLD | NEW |