OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
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 "GrAtlasTextBlob.h" | 8 #include "GrAtlasTextBlob.h" |
9 | 9 |
10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 *vcolor = color; | 130 *vcolor = color; |
131 } | 131 } |
132 | 132 |
133 if (regenTexCoords) { | 133 if (regenTexCoords) { |
134 uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordO ffset); | 134 uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordO ffset); |
135 textureCoords[0] = (uint16_t)u1; | 135 textureCoords[0] = (uint16_t)u1; |
136 textureCoords[1] = (uint16_t)v0; | 136 textureCoords[1] = (uint16_t)v0; |
137 } | 137 } |
138 } | 138 } |
139 | 139 |
140 void GrAtlasTextBlob::LazyGlyphCache::initIfNecessary(Run* run, Run::SubRunInfo* info) { | |
141 // We can reuse if we have a valid strike and our descriptors / typeface are the same. The | |
142 // override descriptor is only for the non-distance field text within a run a run | |
143 const SkDescriptor* newDesc = (run->fOverrideDescriptor && !info->drawAsDist anceFields()) | |
144 ? run->fOverrideDescriptor->getDesc() | |
145 : run->fDescriptor.getDesc(); | |
146 if (!fCache || !SkTypeface::Equal(fTypeface, run->fTypeface) || | |
bungeman-skia
2016/05/18 15:33:07
if instead of using fTypeface here, we just used f
| |
147 fCache->getDescriptor() != *newDesc) { | |
bungeman-skia
2016/05/18 15:33:07
nit: I know it isn't a documented style, but it wo
| |
148 fCache.reset(SkGlyphCache::DetachCache(run->fTypeface, run->fEffects, ne wDesc)); | |
149 SkASSERT(*newDesc == fCache->getDescriptor()); | |
150 fTypeface = run->fTypeface; | |
151 } | |
152 } | |
153 | |
140 template <bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs> | 154 template <bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs> |
141 void GrAtlasTextBlob::regenInBatch(GrDrawBatch::Target* target, | 155 void GrAtlasTextBlob::regenInBatch(GrDrawBatch::Target* target, |
142 GrBatchFontCache* fontCache, | 156 GrBatchFontCache* fontCache, |
143 GrBlobRegenHelper *helper, | 157 GrBlobRegenHelper *helper, |
144 Run* run, | 158 Run* run, |
145 Run::SubRunInfo* info, SkGlyphCache** cache, | 159 Run::SubRunInfo* info, |
146 SkTypeface** typeface, | 160 LazyGlyphCache* lazyCache, |
147 const SkDescriptor** desc, | |
148 int glyphCount, size_t vertexStride, | 161 int glyphCount, size_t vertexStride, |
149 GrColor color, SkScalar transX, | 162 GrColor color, SkScalar transX, |
150 SkScalar transY) const { | 163 SkScalar transY) const { |
151 static_assert(!regenGlyphs || regenTexCoords, "must regenTexCoords along reg enGlyphs"); | 164 static_assert(!regenGlyphs || regenTexCoords, "must regenTexCoords along reg enGlyphs"); |
152 GrBatchTextStrike* strike = nullptr; | 165 GrBatchTextStrike* strike = nullptr; |
153 if (regenTexCoords) { | 166 if (regenTexCoords) { |
154 info->resetBulkUseToken(); | 167 info->resetBulkUseToken(); |
155 | 168 |
156 // We can reuse if we have a valid strike and our descriptors / typeface are the | 169 lazyCache->initIfNecessary(run, info); |
157 // same. The override descriptor is only for the non distance field tex t within | |
158 // a run | |
159 const SkDescriptor* newDesc = (run->fOverrideDescriptor && !info->drawAs DistanceFields()) ? | |
160 run->fOverrideDescriptor->getDesc() : | |
161 run->fDescriptor.getDesc(); | |
162 if (!*cache || !SkTypeface::Equal(*typeface, run->fTypeface) || | |
163 !(**desc == *newDesc)) { | |
164 if (*cache) { | |
165 SkGlyphCache::AttachCache(*cache); | |
166 } | |
167 *desc = newDesc; | |
168 *cache = SkGlyphCache::DetachCache(run->fTypeface, run->fEffects, *d esc); | |
169 *typeface = run->fTypeface; | |
170 } | |
171 | 170 |
172 if (regenGlyphs) { | 171 if (regenGlyphs) { |
173 strike = fontCache->getStrike(*cache); | 172 strike = fontCache->getStrike(lazyCache->cache()); |
174 } else { | 173 } else { |
175 strike = info->strike(); | 174 strike = info->strike(); |
176 } | 175 } |
177 } | 176 } |
178 | 177 |
179 bool brokenRun = false; | 178 bool brokenRun = false; |
180 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { | 179 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { |
181 GrGlyph* glyph = nullptr; | 180 GrGlyph* glyph = nullptr; |
182 int log2Width = 0, log2Height = 0; | 181 int log2Width = 0, log2Height = 0; |
183 if (regenTexCoords) { | 182 if (regenTexCoords) { |
184 size_t glyphOffset = glyphIdx + info->glyphStartIndex(); | 183 size_t glyphOffset = glyphIdx + info->glyphStartIndex(); |
185 | 184 |
186 if (regenGlyphs) { | 185 if (regenGlyphs) { |
187 // Get the id from the old glyph, and use the new strike to look up | 186 // Get the id from the old glyph, and use the new strike to look up |
188 // the glyph. | 187 // the glyph. |
189 GrGlyph::PackedID id = fGlyphs[glyphOffset]->fPackedID; | 188 GrGlyph::PackedID id = fGlyphs[glyphOffset]->fPackedID; |
190 fGlyphs[glyphOffset] = strike->getGlyph(id, info->maskFormat(), *cache); | 189 fGlyphs[glyphOffset] = strike->getGlyph(id, info->maskFormat(), lazyCache->cache()); |
191 SkASSERT(id == fGlyphs[glyphOffset]->fPackedID); | 190 SkASSERT(id == fGlyphs[glyphOffset]->fPackedID); |
192 } | 191 } |
193 glyph = fGlyphs[glyphOffset]; | 192 glyph = fGlyphs[glyphOffset]; |
194 SkASSERT(glyph && glyph->fMaskFormat == info->maskFormat()); | 193 SkASSERT(glyph && glyph->fMaskFormat == info->maskFormat()); |
195 | 194 |
196 if (!fontCache->hasGlyph(glyph) && | 195 if (!fontCache->hasGlyph(glyph) && |
197 !strike->addGlyphToAtlas(target, glyph, *cache, info->maskFormat ())) { | 196 !strike->addGlyphToAtlas(target, glyph, lazyCache->cache(), info ->maskFormat())) { |
198 helper->flush(); | 197 helper->flush(); |
199 brokenRun = glyphIdx > 0; | 198 brokenRun = glyphIdx > 0; |
200 | 199 |
201 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(target, | 200 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(target, |
202 glyph, | 201 glyph, |
203 *cache, | 202 lazyCache->c ache(), |
204 info->maskFo rmat()); | 203 info->maskFo rmat()); |
205 SkASSERT(success); | 204 SkASSERT(success); |
206 } | 205 } |
207 fontCache->addGlyphToBulkAndSetUseToken(info->bulkUseToken(), glyph, | 206 fontCache->addGlyphToBulkAndSetUseToken(info->bulkUseToken(), glyph, |
208 target->nextDrawToken()); | 207 target->nextDrawToken()); |
209 log2Width = fontCache->log2Width(info->maskFormat()); | 208 log2Width = fontCache->log2Width(info->maskFormat()); |
210 log2Height = fontCache->log2Height(info->maskFormat()); | 209 log2Height = fontCache->log2Height(info->maskFormat()); |
211 } | 210 } |
212 | 211 |
213 intptr_t vertex = reinterpret_cast<intptr_t>(fVertices); | 212 intptr_t vertex = reinterpret_cast<intptr_t>(fVertices); |
(...skipping 17 matching lines...) Expand all Loading... | |
231 } | 230 } |
232 | 231 |
233 enum RegenMask { | 232 enum RegenMask { |
234 kNoRegen = 0x0, | 233 kNoRegen = 0x0, |
235 kRegenPos = 0x1, | 234 kRegenPos = 0x1, |
236 kRegenCol = 0x2, | 235 kRegenCol = 0x2, |
237 kRegenTex = 0x4, | 236 kRegenTex = 0x4, |
238 kRegenGlyph = 0x8 | kRegenTex, // we have to regenerate the texture coords w hen we regen glyphs | 237 kRegenGlyph = 0x8 | kRegenTex, // we have to regenerate the texture coords w hen we regen glyphs |
239 | 238 |
240 // combinations | 239 // combinations |
241 kRegenPosCol = kRegenPos | kRegenCol, | 240 kRegenPosCol = kRegenPos | kRegenCol, |
242 kRegenPosTex = kRegenPos | kRegenTex, | 241 kRegenPosTex = kRegenPos | kRegenTex, |
243 kRegenPosTexGlyph = kRegenPos | kRegenGlyph, | 242 kRegenPosTexGlyph = kRegenPos | kRegenGlyph, |
244 kRegenPosColTex = kRegenPos | kRegenCol | kRegenTex, | 243 kRegenPosColTex = kRegenPos | kRegenCol | kRegenTex, |
245 kRegenPosColTexGlyph = kRegenPos | kRegenCol | kRegenGlyph, | 244 kRegenPosColTexGlyph = kRegenPos | kRegenCol | kRegenGlyph, |
246 kRegenColTex = kRegenCol | kRegenTex, | 245 kRegenColTex = kRegenCol | kRegenTex, |
247 kRegenColTexGlyph = kRegenCol | kRegenGlyph, | 246 kRegenColTexGlyph = kRegenCol | kRegenGlyph, |
248 }; | 247 }; |
249 | 248 |
250 #define REGEN_ARGS target, fontCache, helper, &run, &info, cache, typeface, desc , \ | 249 #define REGEN_ARGS target, fontCache, helper, &run, &info, lazyCache, \ |
251 *glyphCount, vertexStride, color, transX, transY | 250 *glyphCount, vertexStride, color, transX, transY |
252 | 251 |
253 void GrAtlasTextBlob::regenInBatch(GrDrawBatch::Target* target, | 252 void GrAtlasTextBlob::regenInBatch(GrDrawBatch::Target* target, |
254 GrBatchFontCache* fontCache, | 253 GrBatchFontCache* fontCache, |
255 GrBlobRegenHelper *helper, | 254 GrBlobRegenHelper *helper, |
256 int runIndex, int subRunIndex, SkGlyphCache** cache, | 255 int runIndex, int subRunIndex, LazyGlyphCache * lazyCache, |
257 SkTypeface** typeface, const SkDescriptor** d esc, | |
258 size_t vertexStride, const SkMatrix& viewMatr ix, | 256 size_t vertexStride, const SkMatrix& viewMatr ix, |
259 SkScalar x, SkScalar y, GrColor color, | 257 SkScalar x, SkScalar y, GrColor color, |
260 void** vertices, size_t* byteCount, int* glyp hCount) { | 258 void** vertices, size_t* byteCount, int* glyp hCount) { |
261 Run& run = fRuns[runIndex]; | 259 Run& run = fRuns[runIndex]; |
262 Run::SubRunInfo& info = run.fSubRunInfo[subRunIndex]; | 260 Run::SubRunInfo& info = run.fSubRunInfo[subRunIndex]; |
263 | 261 |
264 uint64_t currentAtlasGen = fontCache->atlasGeneration(info.maskFormat()); | 262 uint64_t currentAtlasGen = fontCache->atlasGeneration(info.maskFormat()); |
265 | 263 |
266 // Compute translation if any | 264 // Compute translation if any |
267 SkScalar transX, transY; | 265 SkScalar transX, transY; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
310 // set use tokens for all of the glyphs in our subrun. This is only valid if we | 308 // set use tokens for all of the glyphs in our subrun. This is only valid if we |
311 // have a valid atlas generation | 309 // have a valid atlas generation |
312 fontCache->setUseTokenBulk(*info.bulkUseToken(), target->nextDrawTok en(), | 310 fontCache->setUseTokenBulk(*info.bulkUseToken(), target->nextDrawTok en(), |
313 info.maskFormat()); | 311 info.maskFormat()); |
314 break; | 312 break; |
315 } | 313 } |
316 | 314 |
317 *byteCount = info.byteCount(); | 315 *byteCount = info.byteCount(); |
318 *vertices = fVertices + info.vertexStartIndex(); | 316 *vertices = fVertices + info.vertexStartIndex(); |
319 } | 317 } |
OLD | NEW |