OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkGlyphCache.h" | 10 #include "SkGlyphCache.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 SkASSERT(desc); | 79 SkASSERT(desc); |
80 SkASSERT(ctx); | 80 SkASSERT(ctx); |
81 | 81 |
82 fPrev = fNext = NULL; | 82 fPrev = fNext = NULL; |
83 | 83 |
84 fDesc = desc->copy(); | 84 fDesc = desc->copy(); |
85 fScalerContext->getFontMetrics(&fFontMetrics); | 85 fScalerContext->getFontMetrics(&fFontMetrics); |
86 | 86 |
87 // init to 0 so that all of the pointers will be null | 87 // init to 0 so that all of the pointers will be null |
88 memset(fGlyphHash, 0, sizeof(fGlyphHash)); | 88 memset(fGlyphHash, 0, sizeof(fGlyphHash)); |
89 // init with 0xFF so that the charCode field will be -1, which is invalid | 89 |
90 memset(fCharToGlyphHash, 0xFF, sizeof(fCharToGlyphHash)); | |
91 | |
92 fMemoryUsed = sizeof(*this); | 90 fMemoryUsed = sizeof(*this); |
93 | 91 |
94 fGlyphArray.setReserve(kMinGlyphCount); | 92 fGlyphArray.setReserve(kMinGlyphCount); |
95 | 93 |
96 fAuxProcList = NULL; | 94 fAuxProcList = NULL; |
97 } | 95 } |
98 | 96 |
99 SkGlyphCache::~SkGlyphCache() { | 97 SkGlyphCache::~SkGlyphCache() { |
100 #if 0 | 98 #if 0 |
101 { | 99 { |
102 size_t ptrMem = fGlyphArray.count() * sizeof(SkGlyph*); | 100 size_t ptrMem = fGlyphArray.count() * sizeof(SkGlyph*); |
103 size_t glyphAlloc = fGlyphAlloc.totalCapacity(); | 101 size_t glyphAlloc = fGlyphAlloc.totalCapacity(); |
104 size_t glyphHashUsed = 0; | 102 size_t glyphHashUsed = 0; |
105 size_t uniHashUsed = 0; | 103 size_t uniHashUsed = 0; |
106 for (int i = 0; i < kHashCount; ++i) { | 104 for (int i = 0; i < kHashCount; ++i) { |
107 glyphHashUsed += fGlyphHash[i] ? sizeof(fGlyphHash[0]) : 0; | 105 glyphHashUsed += fGlyphHash[i] ? sizeof(fGlyphHash[0]) : 0; |
108 uniHashUsed += fCharToGlyphHash[i].fID != 0xFFFFFFFF ? sizeof(fCharT
oGlyphHash[0]) : 0; | 106 uniHashUsed += fCharToGlyphHash[i].fID != 0xFFFFFFFF ? sizeof(fCharT
oGlyphHash[0]) : 0; |
109 } | 107 } |
110 size_t glyphUsed = fGlyphArray.count() * sizeof(SkGlyph); | 108 size_t glyphUsed = fGlyphArray.count() * sizeof(SkGlyph); |
111 size_t imageUsed = 0; | 109 size_t imageUsed = 0; |
112 for (int i = 0; i < fGlyphArray.count(); ++i) { | 110 for (int i = 0; i < fGlyphArray.count(); ++i) { |
113 const SkGlyph& g = *fGlyphArray[i]; | 111 const SkGlyph& g = *fGlyphArray[i]; |
114 if (g.fImage) { | 112 if (g.fImage) { |
115 imageUsed += g.fHeight * g.rowBytes(); | 113 imageUsed += g.fHeight * g.rowBytes(); |
116 } | 114 } |
117 } | 115 } |
118 | 116 |
119 printf("glyphPtrArray,%zu, Alloc,%zu, imageUsed,%zu, glyphUsed,%zu, glyp
hHashAlloc,%zu, glyphHashUsed,%zu, unicharHashAlloc,%zu, unicharHashUsed,%zu\n", | 117 SkDebugf("glyphPtrArray,%zu, Alloc,%zu, imageUsed,%zu, glyphUsed,%zu, gl
yphHashAlloc,%zu, glyphHashUsed,%zu, unicharHashAlloc,%zu, unicharHashUsed,%zu\n
", |
120 ptrMem, glyphAlloc, imageUsed, glyphUsed, sizeof(fGlyphHash), g
lyphHashUsed, sizeof(fCharToGlyphHash), uniHashUsed); | 118 ptrMem, glyphAlloc, imageUsed, glyphUsed, sizeof(fGlyphHash), g
lyphHashUsed, sizeof(CharGlyphRec) * kHashCount, uniHashUsed); |
121 | 119 |
122 } | 120 } |
123 #endif | 121 #endif |
124 SkGlyph** gptr = fGlyphArray.begin(); | 122 SkGlyph** gptr = fGlyphArray.begin(); |
125 SkGlyph** stop = fGlyphArray.end(); | 123 SkGlyph** stop = fGlyphArray.end(); |
126 while (gptr < stop) { | 124 while (gptr < stop) { |
127 SkPath* path = (*gptr)->fPath; | 125 SkPath* path = (*gptr)->fPath; |
128 if (path) { | 126 if (path) { |
129 SkDELETE(path); | 127 SkDELETE(path); |
130 } | 128 } |
131 gptr += 1; | 129 gptr += 1; |
132 } | 130 } |
133 SkDescriptor::Free(fDesc); | 131 SkDescriptor::Free(fDesc); |
134 SkDELETE(fScalerContext); | 132 SkDELETE(fScalerContext); |
135 this->invokeAndRemoveAuxProcs(); | 133 this->invokeAndRemoveAuxProcs(); |
136 } | 134 } |
137 | 135 |
| 136 SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(uint32_t id) { |
| 137 if (NULL == fCharToGlyphHash.get()) { |
| 138 fCharToGlyphHash.reset(kHashCount); |
| 139 // init with 0xFF so that the charCode field will be -1, which is invali
d |
| 140 memset(fCharToGlyphHash.get(), 0xFF, |
| 141 sizeof(CharGlyphRec) * kHashCount); |
| 142 } |
| 143 |
| 144 return &fCharToGlyphHash[ID2HashIndex(id)]; |
| 145 } |
| 146 |
138 /////////////////////////////////////////////////////////////////////////////// | 147 /////////////////////////////////////////////////////////////////////////////// |
139 | 148 |
140 #ifdef SK_DEBUG | 149 #ifdef SK_DEBUG |
141 #define VALIDATE() AutoValidate av(this) | 150 #define VALIDATE() AutoValidate av(this) |
142 #else | 151 #else |
143 #define VALIDATE() | 152 #define VALIDATE() |
144 #endif | 153 #endif |
145 | 154 |
146 uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) { | 155 uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) { |
147 VALIDATE(); | 156 VALIDATE(); |
148 uint32_t id = SkGlyph::MakeID(charCode); | 157 uint32_t id = SkGlyph::MakeID(charCode); |
149 const CharGlyphRec& rec = fCharToGlyphHash[ID2HashIndex(id)]; | 158 const CharGlyphRec& rec = *this->getCharGlyphRec(id); |
150 | 159 |
151 if (rec.fID == id) { | 160 if (rec.fID == id) { |
152 return rec.fGlyph->getGlyphID(); | 161 return rec.fGlyph->getGlyphID(); |
153 } else { | 162 } else { |
154 return fScalerContext->charToGlyphID(charCode); | 163 return fScalerContext->charToGlyphID(charCode); |
155 } | 164 } |
156 } | 165 } |
157 | 166 |
158 SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) { | 167 SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) { |
159 return fScalerContext->glyphIDToChar(glyphID); | 168 return fScalerContext->glyphIDToChar(glyphID); |
160 } | 169 } |
161 | 170 |
162 unsigned SkGlyphCache::getGlyphCount() { | 171 unsigned SkGlyphCache::getGlyphCount() { |
163 return fScalerContext->getGlyphCount(); | 172 return fScalerContext->getGlyphCount(); |
164 } | 173 } |
165 | 174 |
166 /////////////////////////////////////////////////////////////////////////////// | 175 /////////////////////////////////////////////////////////////////////////////// |
167 | 176 |
168 const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) { | 177 const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) { |
169 VALIDATE(); | 178 VALIDATE(); |
170 uint32_t id = SkGlyph::MakeID(charCode); | 179 uint32_t id = SkGlyph::MakeID(charCode); |
171 CharGlyphRec* rec = &fCharToGlyphHash[ID2HashIndex(id)]; | 180 CharGlyphRec* rec = this->getCharGlyphRec(id); |
172 | 181 |
173 if (rec->fID != id) { | 182 if (rec->fID != id) { |
174 // this ID is based on the UniChar | 183 // this ID is based on the UniChar |
175 rec->fID = id; | 184 rec->fID = id; |
176 // this ID is based on the glyph index | 185 // this ID is based on the glyph index |
177 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode)); | 186 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode)); |
178 rec->fGlyph = this->lookupMetrics(id, kJustAdvance_MetricsType); | 187 rec->fGlyph = this->lookupMetrics(id, kJustAdvance_MetricsType); |
179 } | 188 } |
180 return *rec->fGlyph; | 189 return *rec->fGlyph; |
181 } | 190 } |
182 | 191 |
183 const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) { | 192 const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) { |
184 VALIDATE(); | 193 VALIDATE(); |
185 uint32_t id = SkGlyph::MakeID(glyphID); | 194 uint32_t id = SkGlyph::MakeID(glyphID); |
186 unsigned index = ID2HashIndex(id); | 195 unsigned index = ID2HashIndex(id); |
187 SkGlyph* glyph = fGlyphHash[index]; | 196 SkGlyph* glyph = fGlyphHash[index]; |
188 | 197 |
189 if (NULL == glyph || glyph->fID != id) { | 198 if (NULL == glyph || glyph->fID != id) { |
190 glyph = this->lookupMetrics(glyphID, kJustAdvance_MetricsType); | 199 glyph = this->lookupMetrics(glyphID, kJustAdvance_MetricsType); |
191 fGlyphHash[index] = glyph; | 200 fGlyphHash[index] = glyph; |
192 } | 201 } |
193 return *glyph; | 202 return *glyph; |
194 } | 203 } |
195 | 204 |
196 /////////////////////////////////////////////////////////////////////////////// | 205 /////////////////////////////////////////////////////////////////////////////// |
197 | 206 |
198 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode) { | 207 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode) { |
199 VALIDATE(); | 208 VALIDATE(); |
200 uint32_t id = SkGlyph::MakeID(charCode); | 209 uint32_t id = SkGlyph::MakeID(charCode); |
201 CharGlyphRec* rec = &fCharToGlyphHash[ID2HashIndex(id)]; | 210 CharGlyphRec* rec = this->getCharGlyphRec(id); |
202 | 211 |
203 if (rec->fID != id) { | 212 if (rec->fID != id) { |
204 RecordHashCollisionIf(rec->fGlyph != NULL); | 213 RecordHashCollisionIf(rec->fGlyph != NULL); |
205 // this ID is based on the UniChar | 214 // this ID is based on the UniChar |
206 rec->fID = id; | 215 rec->fID = id; |
207 // this ID is based on the glyph index | 216 // this ID is based on the glyph index |
208 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode)); | 217 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode)); |
209 rec->fGlyph = this->lookupMetrics(id, kFull_MetricsType); | 218 rec->fGlyph = this->lookupMetrics(id, kFull_MetricsType); |
210 } else { | 219 } else { |
211 RecordHashSuccess(); | 220 RecordHashSuccess(); |
212 if (rec->fGlyph->isJustAdvance()) { | 221 if (rec->fGlyph->isJustAdvance()) { |
213 fScalerContext->getMetrics(rec->fGlyph); | 222 fScalerContext->getMetrics(rec->fGlyph); |
214 } | 223 } |
215 } | 224 } |
216 SkASSERT(rec->fGlyph->isFullMetrics()); | 225 SkASSERT(rec->fGlyph->isFullMetrics()); |
217 return *rec->fGlyph; | 226 return *rec->fGlyph; |
218 } | 227 } |
219 | 228 |
220 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode, | 229 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode, |
221 SkFixed x, SkFixed y) { | 230 SkFixed x, SkFixed y) { |
222 VALIDATE(); | 231 VALIDATE(); |
223 uint32_t id = SkGlyph::MakeID(charCode, x, y); | 232 uint32_t id = SkGlyph::MakeID(charCode, x, y); |
224 CharGlyphRec* rec = &fCharToGlyphHash[ID2HashIndex(id)]; | 233 CharGlyphRec* rec = this->getCharGlyphRec(id); |
225 | 234 |
226 if (rec->fID != id) { | 235 if (rec->fID != id) { |
227 RecordHashCollisionIf(rec->fGlyph != NULL); | 236 RecordHashCollisionIf(rec->fGlyph != NULL); |
228 // this ID is based on the UniChar | 237 // this ID is based on the UniChar |
229 rec->fID = id; | 238 rec->fID = id; |
230 // this ID is based on the glyph index | 239 // this ID is based on the glyph index |
231 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode), x, y); | 240 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode), x, y); |
232 rec->fGlyph = this->lookupMetrics(id, kFull_MetricsType); | 241 rec->fGlyph = this->lookupMetrics(id, kFull_MetricsType); |
233 } else { | 242 } else { |
234 RecordHashSuccess(); | 243 RecordHashSuccess(); |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 return tls ? tls->getCacheSizeLimit() : 0; | 710 return tls ? tls->getCacheSizeLimit() : 0; |
702 } | 711 } |
703 | 712 |
704 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { | 713 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { |
705 if (0 == bytes) { | 714 if (0 == bytes) { |
706 SkGlyphCache_Globals::DeleteTLS(); | 715 SkGlyphCache_Globals::DeleteTLS(); |
707 } else { | 716 } else { |
708 SkGlyphCache_Globals::GetTLS().setCacheSizeLimit(bytes); | 717 SkGlyphCache_Globals::GetTLS().setCacheSizeLimit(bytes); |
709 } | 718 } |
710 } | 719 } |
OLD | NEW |