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 |