OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "GrAtlasTextBatch.h" | 8 #include "GrAtlasTextBatch.h" |
9 | 9 |
10 #include "GrBatchFontCache.h" | 10 #include "GrBatchFontCache.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 template <bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs> | 128 template <bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs> |
129 inline void GrAtlasTextBatch::regenBlob(Target* target, FlushInfo* flushInfo, Bl
ob* blob, Run* run, | 129 inline void GrAtlasTextBatch::regenBlob(Target* target, FlushInfo* flushInfo, Bl
ob* blob, Run* run, |
130 TextInfo* info, SkGlyphCache** cache, | 130 TextInfo* info, SkGlyphCache** cache, |
131 SkTypeface** typeface, GrFontScaler** sc
aler, | 131 SkTypeface** typeface, GrFontScaler** sc
aler, |
132 const SkDescriptor** desc, const GrGeome
tryProcessor* gp, | 132 const SkDescriptor** desc, const GrGeome
tryProcessor* gp, |
133 int glyphCount, size_t vertexStride, | 133 int glyphCount, size_t vertexStride, |
134 GrColor color, SkScalar transX, SkScalar
transY) const { | 134 GrColor color, SkScalar transX, SkScalar
transY) const { |
135 static_assert(!regenGlyphs || regenTexCoords, "must regenTexCoords along reg
enGlyphs"); | 135 static_assert(!regenGlyphs || regenTexCoords, "must regenTexCoords along reg
enGlyphs"); |
136 GrBatchTextStrike* strike = nullptr; | 136 GrBatchTextStrike* strike = nullptr; |
137 if (regenTexCoords) { | 137 if (regenTexCoords) { |
138 info->fBulkUseToken.reset(); | 138 info->resetBulkUseToken(); |
139 | 139 |
140 // We can reuse if we have a valid strike and our descriptors / typeface
are the | 140 // We can reuse if we have a valid strike and our descriptors / typeface
are the |
141 // same. The override descriptor is only for the non distance field tex
t within | 141 // same. The override descriptor is only for the non distance field tex
t within |
142 // a run | 142 // a run |
143 const SkDescriptor* newDesc = (run->fOverrideDescriptor && !this->usesDi
stanceFields()) ? | 143 const SkDescriptor* newDesc = (run->fOverrideDescriptor && !this->usesDi
stanceFields()) ? |
144 run->fOverrideDescriptor->getDesc() : | 144 run->fOverrideDescriptor->getDesc() : |
145 run->fDescriptor.getDesc(); | 145 run->fDescriptor.getDesc(); |
146 if (!*cache || !SkTypeface::Equal(*typeface, run->fTypeface) || | 146 if (!*cache || !SkTypeface::Equal(*typeface, run->fTypeface) || |
147 !((*desc)->equals(*newDesc))) { | 147 !((*desc)->equals(*newDesc))) { |
148 if (*cache) { | 148 if (*cache) { |
149 SkGlyphCache::AttachCache(*cache); | 149 SkGlyphCache::AttachCache(*cache); |
150 } | 150 } |
151 *desc = newDesc; | 151 *desc = newDesc; |
152 *cache = SkGlyphCache::DetachCache(run->fTypeface, *desc); | 152 *cache = SkGlyphCache::DetachCache(run->fTypeface, *desc); |
153 *scaler = GrTextContext::GetGrFontScaler(*cache); | 153 *scaler = GrTextContext::GetGrFontScaler(*cache); |
154 strike = info->fStrike; | 154 strike = info->strike(); |
155 *typeface = run->fTypeface; | 155 *typeface = run->fTypeface; |
156 } | 156 } |
157 | 157 |
158 if (regenGlyphs) { | 158 if (regenGlyphs) { |
159 strike = fFontCache->getStrike(*scaler); | 159 strike = fFontCache->getStrike(*scaler); |
160 } else { | 160 } else { |
161 strike = info->fStrike; | 161 strike = info->strike(); |
162 } | 162 } |
163 } | 163 } |
164 | 164 |
165 bool brokenRun = false; | 165 bool brokenRun = false; |
166 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { | 166 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { |
167 GrGlyph* glyph = nullptr; | 167 GrGlyph* glyph = nullptr; |
168 if (regenTexCoords) { | 168 if (regenTexCoords) { |
169 size_t glyphOffset = glyphIdx + info->fGlyphStartIndex; | 169 size_t glyphOffset = glyphIdx + info->glyphStartIndex(); |
170 | 170 |
171 if (regenGlyphs) { | 171 if (regenGlyphs) { |
172 // Get the id from the old glyph, and use the new strike to look
up | 172 // Get the id from the old glyph, and use the new strike to look
up |
173 // the glyph. | 173 // the glyph. |
174 GrGlyph::PackedID id = blob->fGlyphs[glyphOffset]->fPackedID; | 174 GrGlyph::PackedID id = blob->fGlyphs[glyphOffset]->fPackedID; |
175 blob->fGlyphs[glyphOffset] = strike->getGlyph(id, this->maskForm
at(), *scaler); | 175 blob->fGlyphs[glyphOffset] = strike->getGlyph(id, this->maskForm
at(), *scaler); |
176 SkASSERT(id == blob->fGlyphs[glyphOffset]->fPackedID); | 176 SkASSERT(id == blob->fGlyphs[glyphOffset]->fPackedID); |
177 } | 177 } |
178 glyph = blob->fGlyphs[glyphOffset]; | 178 glyph = blob->fGlyphs[glyphOffset]; |
179 SkASSERT(glyph && glyph->fMaskFormat == this->maskFormat()); | 179 SkASSERT(glyph && glyph->fMaskFormat == this->maskFormat()); |
180 | 180 |
181 if (!fFontCache->hasGlyph(glyph) && | 181 if (!fFontCache->hasGlyph(glyph) && |
182 !strike->addGlyphToAtlas(target, glyph, *scaler, this->maskForma
t())) { | 182 !strike->addGlyphToAtlas(target, glyph, *scaler, this->maskForma
t())) { |
183 this->flush(target, flushInfo); | 183 this->flush(target, flushInfo); |
184 target->initDraw(gp, this->pipeline()); | 184 target->initDraw(gp, this->pipeline()); |
185 brokenRun = glyphIdx > 0; | 185 brokenRun = glyphIdx > 0; |
186 | 186 |
187 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(target, | 187 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(target, |
188 glyph, | 188 glyph, |
189 *scaler, | 189 *scaler, |
190 this->maskFo
rmat()); | 190 this->maskFo
rmat()); |
191 SkASSERT(success); | 191 SkASSERT(success); |
192 } | 192 } |
193 fFontCache->addGlyphToBulkAndSetUseToken(&info->fBulkUseToken, glyph
, | 193 fFontCache->addGlyphToBulkAndSetUseToken(info->bulkUseToken(), glyph
, |
194 target->currentToken()); | 194 target->currentToken()); |
195 } | 195 } |
196 | 196 |
197 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices); | 197 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices); |
198 vertex += info->fVertexStartIndex; | 198 vertex += info->vertexStartIndex(); |
199 vertex += vertexStride * glyphIdx * GrAtlasTextBatch::kVerticesPerGlyph; | 199 vertex += vertexStride * glyphIdx * GrAtlasTextBatch::kVerticesPerGlyph; |
200 regen_vertices<regenPos, regenCol, regenTexCoords>(vertex, glyph, vertex
Stride, | 200 regen_vertices<regenPos, regenCol, regenTexCoords>(vertex, glyph, vertex
Stride, |
201 this->usesDistanceFie
lds(), transX, | 201 this->usesDistanceFie
lds(), transX, |
202 transY, color); | 202 transY, color); |
203 flushInfo->fGlyphsToFlush++; | 203 flushInfo->fGlyphsToFlush++; |
204 } | 204 } |
205 | 205 |
206 // We my have changed the color so update it here | 206 // We my have changed the color so update it here |
207 run->fColor = color; | 207 run->fColor = color; |
208 if (regenTexCoords) { | 208 if (regenTexCoords) { |
209 if (regenGlyphs) { | 209 if (regenGlyphs) { |
210 info->fStrike.reset(SkRef(strike)); | 210 info->setStrike(strike); |
211 } | 211 } |
212 info->fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAtlasGenerati
on : | 212 info->setAtlasGeneration(brokenRun ? GrBatchAtlas::kInvalidAtlasGenerati
on : |
213 fFontCache->atlasGeneration(this->m
askFormat()); | 213 fFontCache->atlasGeneration(this->m
askFormat())); |
214 } | 214 } |
215 } | 215 } |
216 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 216 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
217 | 217 |
218 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { | 218 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { |
219 unsigned r = SkColorGetR(c); | 219 unsigned r = SkColorGetR(c); |
220 unsigned g = SkColorGetG(c); | 220 unsigned g = SkColorGetG(c); |
221 unsigned b = SkColorGetB(c); | 221 unsigned b = SkColorGetB(c); |
222 return GrColorPackRGBA(r, g, b, 0xff); | 222 return GrColorPackRGBA(r, g, b, 0xff); |
223 } | 223 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 uint64_t currentAtlasGen = fFontCache->atlasGeneration(maskFormat); | 371 uint64_t currentAtlasGen = fFontCache->atlasGeneration(maskFormat); |
372 | 372 |
373 // Because the GrBatchFontCache may evict the strike a blob depends on u
sing for | 373 // Because the GrBatchFontCache may evict the strike a blob depends on u
sing for |
374 // generating its texture coords, we have to track whether or not the st
rike has | 374 // generating its texture coords, we have to track whether or not the st
rike has |
375 // been abandoned. If it hasn't been abandoned, then we can use the GrG
lyph*s as is | 375 // been abandoned. If it hasn't been abandoned, then we can use the GrG
lyph*s as is |
376 // otherwise we have to get the new strike, and use that to get the corr
ect glyphs. | 376 // otherwise we have to get the new strike, and use that to get the corr
ect glyphs. |
377 // Because we do not have the packed ids, and thus can't look up our gly
phs in the | 377 // Because we do not have the packed ids, and thus can't look up our gly
phs in the |
378 // new strike, we instead keep our ref to the old strike and use the pac
ked ids from | 378 // new strike, we instead keep our ref to the old strike and use the pac
ked ids from |
379 // it. These ids will still be valid as long as we hold the ref. When
we are done | 379 // it. These ids will still be valid as long as we hold the ref. When
we are done |
380 // updating our cache of the GrGlyph*s, we drop our ref on the old strik
e | 380 // updating our cache of the GrGlyph*s, we drop our ref on the old strik
e |
381 bool regenerateGlyphs = info.fStrike->isAbandoned(); | 381 bool regenerateGlyphs = info.strike()->isAbandoned(); |
382 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlasGen
|| | 382 bool regenerateTextureCoords = info.atlasGeneration() != currentAtlasGen
|| |
383 regenerateGlyphs; | 383 regenerateGlyphs; |
384 bool regenerateColors; | 384 bool regenerateColors; |
385 if (usesDistanceFields) { | 385 if (usesDistanceFields) { |
386 regenerateColors = !isLCD && run.fColor != args.fColor; | 386 regenerateColors = !isLCD && run.fColor != args.fColor; |
387 } else { | 387 } else { |
388 regenerateColors = kA8_GrMaskFormat == maskFormat && run.fColor != a
rgs.fColor; | 388 regenerateColors = kA8_GrMaskFormat == maskFormat && run.fColor != a
rgs.fColor; |
389 } | 389 } |
390 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f; | 390 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f; |
391 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; | 391 int glyphCount = info.glyphCount(); |
392 | 392 |
393 uint32_t regenMaskBits = kNoRegen; | 393 uint32_t regenMaskBits = kNoRegen; |
394 regenMaskBits |= regeneratePositions ? kRegenPos : 0; | 394 regenMaskBits |= regeneratePositions ? kRegenPos : 0; |
395 regenMaskBits |= regenerateColors ? kRegenCol : 0; | 395 regenMaskBits |= regenerateColors ? kRegenCol : 0; |
396 regenMaskBits |= regenerateTextureCoords ? kRegenTex : 0; | 396 regenMaskBits |= regenerateTextureCoords ? kRegenTex : 0; |
397 regenMaskBits |= regenerateGlyphs ? kRegenGlyph : 0; | 397 regenMaskBits |= regenerateGlyphs ? kRegenGlyph : 0; |
398 RegenMask regenMask = (RegenMask)regenMaskBits; | 398 RegenMask regenMask = (RegenMask)regenMaskBits; |
399 | 399 |
400 switch (regenMask) { | 400 switch (regenMask) { |
401 case kRegenPos: this->regenBlob<true, false, false, false>(REGEN_ARG
S); break; | 401 case kRegenPos: this->regenBlob<true, false, false, false>(REGEN_ARG
S); break; |
402 case kRegenCol: this->regenBlob<false, true, false, false>(REGEN_ARG
S); break; | 402 case kRegenCol: this->regenBlob<false, true, false, false>(REGEN_ARG
S); break; |
403 case kRegenTex: this->regenBlob<false, false, true, false>(REGEN_ARG
S); break; | 403 case kRegenTex: this->regenBlob<false, false, true, false>(REGEN_ARG
S); break; |
404 case kRegenGlyph: this->regenBlob<false, false, true, true>(REGEN_AR
GS); break; | 404 case kRegenGlyph: this->regenBlob<false, false, true, true>(REGEN_AR
GS); break; |
405 | 405 |
406 // combinations | 406 // combinations |
407 case kRegenPosCol: this->regenBlob<true, true, false, false>(REGEN_A
RGS); break; | 407 case kRegenPosCol: this->regenBlob<true, true, false, false>(REGEN_A
RGS); break; |
408 case kRegenPosTex: this->regenBlob<true, false, true, false>(REGEN_A
RGS); break; | 408 case kRegenPosTex: this->regenBlob<true, false, true, false>(REGEN_A
RGS); break; |
409 case kRegenPosTexGlyph: this->regenBlob<true, false, true, true>(REG
EN_ARGS); break; | 409 case kRegenPosTexGlyph: this->regenBlob<true, false, true, true>(REG
EN_ARGS); break; |
410 case kRegenPosColTex: this->regenBlob<true, true, true, false>(REGEN
_ARGS); break; | 410 case kRegenPosColTex: this->regenBlob<true, true, true, false>(REGEN
_ARGS); break; |
411 case kRegenPosColTexGlyph: this->regenBlob<true, true, true, true>(R
EGEN_ARGS); break; | 411 case kRegenPosColTexGlyph: this->regenBlob<true, true, true, true>(R
EGEN_ARGS); break; |
412 case kRegenColTex: this->regenBlob<false, true, true, false>(REGEN_A
RGS); break; | 412 case kRegenColTex: this->regenBlob<false, true, true, false>(REGEN_A
RGS); break; |
413 case kRegenColTexGlyph: this->regenBlob<false, true, true, true>(REG
EN_ARGS); break; | 413 case kRegenColTexGlyph: this->regenBlob<false, true, true, true>(REG
EN_ARGS); break; |
414 case kNoRegen: | 414 case kNoRegen: |
415 flushInfo.fGlyphsToFlush += glyphCount; | 415 flushInfo.fGlyphsToFlush += glyphCount; |
416 | 416 |
417 // set use tokens for all of the glyphs in our subrun. This is
only valid if we | 417 // set use tokens for all of the glyphs in our subrun. This is
only valid if we |
418 // have a valid atlas generation | 418 // have a valid atlas generation |
419 fFontCache->setUseTokenBulk(info.fBulkUseToken, target->currentT
oken(), maskFormat); | 419 fFontCache->setUseTokenBulk(*info.bulkUseToken(), target->curren
tToken(), |
| 420 maskFormat); |
420 break; | 421 break; |
421 } | 422 } |
422 | 423 |
423 // now copy all vertices | 424 // now copy all vertices |
424 size_t byteCount = info.fVertexEndIndex - info.fVertexStartIndex; | 425 size_t byteCount = info.byteCount(); |
425 memcpy(currVertex, blob->fVertices + info.fVertexStartIndex, byteCount); | 426 memcpy(currVertex, blob->fVertices + info.vertexStartIndex(), byteCount)
; |
426 | 427 |
427 currVertex += byteCount; | 428 currVertex += byteCount; |
428 } | 429 } |
429 | 430 |
430 // Make sure to attach the last cache if applicable | 431 // Make sure to attach the last cache if applicable |
431 if (cache) { | 432 if (cache) { |
432 SkGlyphCache::AttachCache(cache); | 433 SkGlyphCache::AttachCache(cache); |
433 } | 434 } |
434 this->flush(target, &flushInfo); | 435 this->flush(target, &flushInfo); |
435 } | 436 } |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 return GrDistanceFieldA8TextGeoProc::Create(color, | 567 return GrDistanceFieldA8TextGeoProc::Create(color, |
567 viewMatrix, | 568 viewMatrix, |
568 texture, | 569 texture, |
569 params, | 570 params, |
570 flags, | 571 flags, |
571 this->usesLocalCoords()); | 572 this->usesLocalCoords()); |
572 #endif | 573 #endif |
573 } | 574 } |
574 | 575 |
575 } | 576 } |
OLD | NEW |