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

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

Issue 880383002: Make char hash dynamic when needed. (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 /* 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
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
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 }
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