Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: src/core/SkGlyphCache.cpp

Issue 897463004: Revert of Make the glyph array entries inline. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkGlyphCache.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkGlyphCache.h" 8 #include "SkGlyphCache.h"
9 #include "SkGlyphCache_Globals.h" 9 #include "SkGlyphCache_Globals.h"
10 #include "SkGraphics.h" 10 #include "SkGraphics.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca lerContext* ctx) 59 SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca lerContext* ctx)
60 : fScalerContext(ctx), fGlyphAlloc(kMinAllocAmount) { 60 : fScalerContext(ctx), fGlyphAlloc(kMinAllocAmount) {
61 SkASSERT(typeface); 61 SkASSERT(typeface);
62 SkASSERT(desc); 62 SkASSERT(desc);
63 SkASSERT(ctx); 63 SkASSERT(ctx);
64 64
65 fPrev = fNext = NULL; 65 fPrev = fNext = NULL;
66 66
67 fDesc = desc->copy(); 67 fDesc = desc->copy();
68 fScalerContext->getFontMetrics(&fFontMetrics); 68 fScalerContext->getFontMetrics(&fFontMetrics);
69
70 // init to 0 so that all of the pointers will be null
71 memset(fGlyphHash, 0, sizeof(fGlyphHash));
69 72
70 // Create the sentinel SkGlyph.
71 SkGlyph* sentinel = fGlyphArray.insert(kSentinelGlyphID);
72 sentinel->init(0);
73
74 // Initialize all index to zero which points to the sentinel SkGlyph.
75 memset(fGlyphHash, 0x00, sizeof(fGlyphHash));
76
77 fMemoryUsed = sizeof(*this); 73 fMemoryUsed = sizeof(*this);
78 74
79 fGlyphArray.setReserve(kMinGlyphCount); 75 fGlyphArray.setReserve(kMinGlyphCount);
80 76
81 fAuxProcList = NULL; 77 fAuxProcList = NULL;
82 78
83 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS 79 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
84 fHashHitCount = fHashMissCount = 0; 80 fHashHitCount = fHashMissCount = 0;
85 #endif 81 #endif
86 } 82 }
(...skipping 16 matching lines...) Expand all
103 if (g.fImage) { 99 if (g.fImage) {
104 imageUsed += g.fHeight * g.rowBytes(); 100 imageUsed += g.fHeight * g.rowBytes();
105 } 101 }
106 } 102 }
107 103
108 SkDebugf("glyphPtrArray,%zu, Alloc,%zu, imageUsed,%zu, glyphUsed,%zu, gl yphHashAlloc,%zu, glyphHashUsed,%zu, unicharHashAlloc,%zu, unicharHashUsed,%zu\n ", 104 SkDebugf("glyphPtrArray,%zu, Alloc,%zu, imageUsed,%zu, glyphUsed,%zu, gl yphHashAlloc,%zu, glyphHashUsed,%zu, unicharHashAlloc,%zu, unicharHashUsed,%zu\n ",
109 ptrMem, glyphAlloc, imageUsed, glyphUsed, sizeof(fGlyphHash), g lyphHashUsed, sizeof(CharGlyphRec) * kHashCount, uniHashUsed); 105 ptrMem, glyphAlloc, imageUsed, glyphUsed, sizeof(fGlyphHash), g lyphHashUsed, sizeof(CharGlyphRec) * kHashCount, uniHashUsed);
110 106
111 } 107 }
112 #endif 108 #endif
113 SkGlyph* gptr = fGlyphArray.begin(); 109 SkGlyph** gptr = fGlyphArray.begin();
114 SkGlyph* stop = fGlyphArray.end(); 110 SkGlyph** stop = fGlyphArray.end();
115 while (gptr < stop) { 111 while (gptr < stop) {
116 SkPath* path = gptr->fPath; 112 SkPath* path = (*gptr)->fPath;
117 if (path) { 113 if (path) {
118 SkDELETE(path); 114 SkDELETE(path);
119 } 115 }
120 gptr += 1; 116 gptr += 1;
121 } 117 }
122 SkDescriptor::Free(fDesc); 118 SkDescriptor::Free(fDesc);
123 SkDELETE(fScalerContext); 119 SkDELETE(fScalerContext);
124 this->invokeAndRemoveAuxProcs(); 120 this->invokeAndRemoveAuxProcs();
125 } 121 }
126 122
127 SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(uint32_t id) { 123 SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(uint32_t id) {
128 if (NULL == fCharToGlyphHash.get()) { 124 if (NULL == fCharToGlyphHash.get()) {
129 // Allocate the array.
130 fCharToGlyphHash.reset(kHashCount); 125 fCharToGlyphHash.reset(kHashCount);
131 // Initialize entries of fCharToGlyphHash to index the sentinel glyph. 126 // init with 0xFF so that the charCode field will be -1, which is invali d
132 memset(fCharToGlyphHash.get(), 0x00, 127 memset(fCharToGlyphHash.get(), 0xFF,
133 sizeof(CharGlyphRec) * kHashCount); 128 sizeof(CharGlyphRec) * kHashCount);
134 } 129 }
135 130
136 return &fCharToGlyphHash[ID2HashIndex(id)]; 131 return &fCharToGlyphHash[ID2HashIndex(id)];
137 } 132 }
138 133
139 void SkGlyphCache::adjustCaches(int insertion_index) {
140 for (int i = 0; i < kHashCount; ++i) {
141 if (fGlyphHash[i] >= SkToU16(insertion_index)) {
142 fGlyphHash[i] += 1;
143 }
144 }
145 if (fCharToGlyphHash.get() != NULL) {
146 for (int i = 0; i < kHashCount; ++i) {
147 if (fCharToGlyphHash[i].fGlyphIndex >= SkToU16(insertion_index)) {
148 fCharToGlyphHash[i].fGlyphIndex += 1;
149 }
150 }
151 }
152 }
153
154 /////////////////////////////////////////////////////////////////////////////// 134 ///////////////////////////////////////////////////////////////////////////////
155 135
156 #ifdef SK_DEBUG 136 #ifdef SK_DEBUG
157 #define VALIDATE() AutoValidate av(this) 137 #define VALIDATE() AutoValidate av(this)
158 #else 138 #else
159 #define VALIDATE() 139 #define VALIDATE()
160 #endif 140 #endif
161 141
162 uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) { 142 uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) {
163 VALIDATE(); 143 VALIDATE();
164 uint32_t id = SkGlyph::MakeID(charCode); 144 uint32_t id = SkGlyph::MakeID(charCode);
165 const CharGlyphRec& rec = *this->getCharGlyphRec(id); 145 const CharGlyphRec& rec = *this->getCharGlyphRec(id);
166 146
167 if (rec.fID == id) { 147 if (rec.fID == id) {
168 return fGlyphArray[rec.fGlyphIndex].getGlyphID(); 148 return rec.fGlyph->getGlyphID();
169 } else { 149 } else {
170 return fScalerContext->charToGlyphID(charCode); 150 return fScalerContext->charToGlyphID(charCode);
171 } 151 }
172 } 152 }
173 153
174 SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) { 154 SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) {
175 return fScalerContext->glyphIDToChar(glyphID); 155 return fScalerContext->glyphIDToChar(glyphID);
176 } 156 }
177 157
178 unsigned SkGlyphCache::getGlyphCount() { 158 unsigned SkGlyphCache::getGlyphCount() {
179 return fScalerContext->getGlyphCount(); 159 return fScalerContext->getGlyphCount();
180 } 160 }
181 161
182 /////////////////////////////////////////////////////////////////////////////// 162 ///////////////////////////////////////////////////////////////////////////////
183 163
184 const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) { 164 const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) {
185 VALIDATE(); 165 VALIDATE();
186 return *this->lookupByChar(charCode, kJustAdvance_MetricsType); 166 uint32_t id = SkGlyph::MakeID(charCode);
167 CharGlyphRec* rec = this->getCharGlyphRec(id);
168
169 if (rec->fID != id) {
170 // this ID is based on the UniChar
171 rec->fID = id;
172 // this ID is based on the glyph index
173 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode));
174 rec->fGlyph = this->lookupMetrics(id, kJustAdvance_MetricsType);
175 }
176 return *rec->fGlyph;
187 } 177 }
188 178
189 const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) { 179 const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) {
190 VALIDATE(); 180 VALIDATE();
191 uint32_t id = SkGlyph::MakeID(glyphID); 181 uint32_t id = SkGlyph::MakeID(glyphID);
192 return *this->lookupByChar(id, kJustAdvance_MetricsType); 182 unsigned index = ID2HashIndex(id);
183 SkGlyph* glyph = fGlyphHash[index];
193 184
185 if (NULL == glyph || glyph->fID != id) {
186 glyph = this->lookupMetrics(glyphID, kJustAdvance_MetricsType);
187 fGlyphHash[index] = glyph;
188 }
189 return *glyph;
194 } 190 }
195 191
196 /////////////////////////////////////////////////////////////////////////////// 192 ///////////////////////////////////////////////////////////////////////////////
197 193
198 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode) { 194 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode) {
199 VALIDATE(); 195 VALIDATE();
200 return *this->lookupByChar(charCode, kFull_MetricsType); 196 uint32_t id = SkGlyph::MakeID(charCode);
197 CharGlyphRec* rec = this->getCharGlyphRec(id);
198
199 if (rec->fID != id) {
200 RecordHashCollisionIf(rec->fGlyph != NULL);
201 // this ID is based on the UniChar
202 rec->fID = id;
203 // this ID is based on the glyph index
204 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode));
205 rec->fGlyph = this->lookupMetrics(id, kFull_MetricsType);
206 } else {
207 RecordHashSuccess();
208 if (rec->fGlyph->isJustAdvance()) {
209 fScalerContext->getMetrics(rec->fGlyph);
210 }
211 }
212 SkASSERT(rec->fGlyph->isFullMetrics());
213 return *rec->fGlyph;
201 } 214 }
202 215
203 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode, 216 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode,
204 SkFixed x, SkFixed y) { 217 SkFixed x, SkFixed y) {
205 VALIDATE(); 218 VALIDATE();
206 return *this->lookupByChar(charCode, kFull_MetricsType, x, y); 219 uint32_t id = SkGlyph::MakeID(charCode, x, y);
220 CharGlyphRec* rec = this->getCharGlyphRec(id);
221
222 if (rec->fID != id) {
223 RecordHashCollisionIf(rec->fGlyph != NULL);
224 // this ID is based on the UniChar
225 rec->fID = id;
226 // this ID is based on the glyph index
227 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode), x, y);
228 rec->fGlyph = this->lookupMetrics(id, kFull_MetricsType);
229 } else {
230 RecordHashSuccess();
231 if (rec->fGlyph->isJustAdvance()) {
232 fScalerContext->getMetrics(rec->fGlyph);
233 }
234 }
235 SkASSERT(rec->fGlyph->isFullMetrics());
236 return *rec->fGlyph;
207 } 237 }
208 238
209 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) { 239 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) {
210 VALIDATE(); 240 VALIDATE();
211 uint32_t id = SkGlyph::MakeID(glyphID); 241 uint32_t id = SkGlyph::MakeID(glyphID);
212 return *this->lookupByCombinedID(id, kFull_MetricsType); 242 unsigned index = ID2HashIndex(id);
243 SkGlyph* glyph = fGlyphHash[index];
244
245 if (NULL == glyph || glyph->fID != id) {
246 RecordHashCollisionIf(glyph != NULL);
247 glyph = this->lookupMetrics(glyphID, kFull_MetricsType);
248 fGlyphHash[index] = glyph;
249 } else {
250 RecordHashSuccess();
251 if (glyph->isJustAdvance()) {
252 fScalerContext->getMetrics(glyph);
253 }
254 }
255 SkASSERT(glyph->isFullMetrics());
256 return *glyph;
213 } 257 }
214 258
215 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi xed y) { 259 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi xed y) {
216 VALIDATE(); 260 VALIDATE();
217 uint32_t id = SkGlyph::MakeID(glyphID, x, y); 261 uint32_t id = SkGlyph::MakeID(glyphID, x, y);
218 return *this->lookupByCombinedID(id, kFull_MetricsType); 262 unsigned index = ID2HashIndex(id);
219 } 263 SkGlyph* glyph = fGlyphHash[index];
220 264
221 SkGlyph* SkGlyphCache::lookupByChar(SkUnichar charCode, MetricsType type, SkFixe d x, SkFixed y) { 265 if (NULL == glyph || glyph->fID != id) {
222 uint32_t id = SkGlyph::MakeID(charCode, x, y); 266 RecordHashCollisionIf(glyph != NULL);
223 CharGlyphRec* rec = this->getCharGlyphRec(id); 267 glyph = this->lookupMetrics(id, kFull_MetricsType);
224 SkGlyph* glyph; 268 fGlyphHash[index] = glyph;
225 if (rec->fID != id) {
226 RecordHashCollisionIf(glyph_index != kSentinelGlyphIndex);
227 // this ID is based on the UniChar
228 rec->fID = id;
229 // this ID is based on the glyph index
230 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode), x, y);
231 rec->fGlyphIndex = this->lookupMetrics(id, type);
232 glyph = &fGlyphArray[rec->fGlyphIndex];
233 } else { 269 } else {
234 RecordHashSuccess(); 270 RecordHashSuccess();
235 glyph = &fGlyphArray[rec->fGlyphIndex]; 271 if (glyph->isJustAdvance()) {
236 if (type == kFull_MetricsType && glyph->isJustAdvance()) {
237 fScalerContext->getMetrics(glyph); 272 fScalerContext->getMetrics(glyph);
238 } 273 }
239 } 274 }
240 return glyph; 275 SkASSERT(glyph->isFullMetrics());
276 return *glyph;
241 } 277 }
242 278
243 SkGlyph* SkGlyphCache::lookupByCombinedID(uint32_t id, MetricsType type) { 279 SkGlyph* SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) {
244 uint32_t hash_index = ID2HashIndex(id); 280 SkGlyph* glyph;
245 uint16_t glyph_index = fGlyphHash[hash_index]; 281
246 SkGlyph* glyph = &fGlyphArray[glyph_index]; 282 int hi = 0;
247 283 int count = fGlyphArray.count();
248 if (glyph->fID != id) { 284
249 RecordHashCollisionIf(glyph_index != kSentinelGlyphIndex); 285 if (count) {
250 glyph_index = this->lookupMetrics(id, type); 286 SkGlyph** gptr = fGlyphArray.begin();
251 fGlyphHash[hash_index] = glyph_index; 287 int lo = 0;
252 glyph = &fGlyphArray[glyph_index]; 288
253 } else { 289 hi = count - 1;
254 RecordHashSuccess(); 290 while (lo < hi) {
255 if (type == kFull_MetricsType && glyph->isJustAdvance()) { 291 int mid = (hi + lo) >> 1;
256 fScalerContext->getMetrics(glyph); 292 if (gptr[mid]->fID < id) {
293 lo = mid + 1;
294 } else {
295 hi = mid;
296 }
257 } 297 }
258 } 298 glyph = gptr[hi];
259 return glyph; 299 if (glyph->fID == id) {
260 } 300 if (kFull_MetricsType == mtype && glyph->isJustAdvance()) {
301 fScalerContext->getMetrics(glyph);
302 }
303 return glyph;
304 }
261 305
262 uint16_t SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) { 306 // check if we need to bump hi before falling though to the allocator
263 // Count is always greater than 0 because of the sentinel. 307 if (glyph->fID < id) {
264 SkGlyph* gptr = fGlyphArray.begin(); 308 hi += 1;
265 int lo = 0;
266 int hi = fGlyphArray.count() - 1;
267 while (lo < hi) {
268 int mid = (hi + lo) >> 1;
269 if (gptr[mid].fID < id) {
270 lo = mid + 1;
271 } else {
272 hi = mid;
273 } 309 }
274 } 310 }
275 311
276 uint16_t glyph_index = hi;
277 SkGlyph* glyph = &gptr[glyph_index];
278 if (glyph->fID == id) {
279 if (kFull_MetricsType == mtype && glyph->isJustAdvance()) {
280 fScalerContext->getMetrics(glyph);
281 }
282 SkASSERT(glyph_index != kSentinelGlyphIndex);
283 return glyph_index;
284 }
285
286 // check if we need to bump hi before falling though to the allocator
287 if (glyph->fID < id) {
288 glyph_index += 1;
289 }
290
291 // not found, but hi tells us where to inser the new glyph 312 // not found, but hi tells us where to inser the new glyph
292 fMemoryUsed += sizeof(SkGlyph); 313 fMemoryUsed += sizeof(SkGlyph);
293
294 this->adjustCaches(glyph_index);
295 314
296 glyph = fGlyphArray.insert(glyph_index); 315 glyph = (SkGlyph*)fGlyphAlloc.alloc(sizeof(SkGlyph),
316 SkChunkAlloc::kThrow_AllocFailType);
297 glyph->init(id); 317 glyph->init(id);
318 *fGlyphArray.insert(hi) = glyph;
298 319
299 if (kJustAdvance_MetricsType == mtype) { 320 if (kJustAdvance_MetricsType == mtype) {
300 fScalerContext->getAdvance(glyph); 321 fScalerContext->getAdvance(glyph);
301 } else { 322 } else {
302 SkASSERT(kFull_MetricsType == mtype); 323 SkASSERT(kFull_MetricsType == mtype);
303 fScalerContext->getMetrics(glyph); 324 fScalerContext->getMetrics(glyph);
304 } 325 }
305 326
306 SkASSERT(glyph_index != kSentinelGlyphIndex); 327 return glyph;
307 return glyph_index;
308 } 328 }
309 329
310 const void* SkGlyphCache::findImage(const SkGlyph& glyph) { 330 const void* SkGlyphCache::findImage(const SkGlyph& glyph) {
311 if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) { 331 if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) {
312 if (NULL == glyph.fImage) { 332 if (NULL == glyph.fImage) {
313 size_t size = glyph.computeImageSize(); 333 size_t size = glyph.computeImageSize();
314 const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size, 334 const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size,
315 SkChunkAlloc::kReturnNil_AllocFailType); 335 SkChunkAlloc::kReturnNil_AllocFailType);
316 // check that alloc() actually succeeded 336 // check that alloc() actually succeeded
317 if (glyph.fImage) { 337 if (glyph.fImage) {
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 return tls ? tls->getCacheSizeLimit() : 0; 746 return tls ? tls->getCacheSizeLimit() : 0;
727 } 747 }
728 748
729 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { 749 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) {
730 if (0 == bytes) { 750 if (0 == bytes) {
731 SkGlyphCache_Globals::DeleteTLS(); 751 SkGlyphCache_Globals::DeleteTLS();
732 } else { 752 } else {
733 SkGlyphCache_Globals::GetTLS().setCacheSizeLimit(bytes); 753 SkGlyphCache_Globals::GetTLS().setCacheSizeLimit(bytes);
734 } 754 }
735 } 755 }
OLDNEW
« no previous file with comments | « src/core/SkGlyphCache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698