| 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 |