1ddd22d86455d95941ea21253b210819c1d4a3863joshualitt/* 2ddd22d86455d95941ea21253b210819c1d4a3863joshualitt * Copyright 2016 Google Inc. 3ddd22d86455d95941ea21253b210819c1d4a3863joshualitt * 4ddd22d86455d95941ea21253b210819c1d4a3863joshualitt * Use of this source code is governed by a BSD-style license that can be 5ddd22d86455d95941ea21253b210819c1d4a3863joshualitt * found in the LICENSE file. 6ddd22d86455d95941ea21253b210819c1d4a3863joshualitt */ 7ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 8ddd22d86455d95941ea21253b210819c1d4a3863joshualitt#include "GrAtlasTextBlob.h" 9ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 10742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon#include "GrOpFlushState.h" 118e84a1ed07ad5d529d381d43302e597f31723076joshualitt#include "GrTextUtils.h" 12ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 13ddd22d86455d95941ea21253b210819c1d4a3863joshualitt#include "SkDistanceFieldGen.h" 14ddd22d86455d95941ea21253b210819c1d4a3863joshualitt#include "SkGlyphCache.h" 15ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 16895274391db8df7357334aec260edca2e1735626Brian Salomon#include "ops/GrAtlasTextOp.h" 17ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 18ddd22d86455d95941ea21253b210819c1d4a3863joshualitt//////////////////////////////////////////////////////////////////////////////////////////////////// 19ddd22d86455d95941ea21253b210819c1d4a3863joshualitt// A large template to handle regenerating the vertices of a textblob with as few branches as 20ddd22d86455d95941ea21253b210819c1d4a3863joshualitt// possible 21ddd22d86455d95941ea21253b210819c1d4a3863joshualitttemplate <bool regenPos, bool regenCol, bool regenTexCoords> 22ddd22d86455d95941ea21253b210819c1d4a3863joshualittinline void regen_vertices(intptr_t vertex, const GrGlyph* glyph, size_t vertexStride, 23ddd22d86455d95941ea21253b210819c1d4a3863joshualitt bool useDistanceFields, SkScalar transX, SkScalar transY, 247023a00c35d904e4ccff09c377e9ba26abba6181jvanverth int32_t log2Width, int32_t log2Height, 25ddd22d86455d95941ea21253b210819c1d4a3863joshualitt GrColor color) { 26ddd22d86455d95941ea21253b210819c1d4a3863joshualitt int u0, v0, u1, v1; 27ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenTexCoords) { 28ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkASSERT(glyph); 29ddd22d86455d95941ea21253b210819c1d4a3863joshualitt int width = glyph->fBounds.width(); 30ddd22d86455d95941ea21253b210819c1d4a3863joshualitt int height = glyph->fBounds.height(); 31ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 32ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (useDistanceFields) { 33ddd22d86455d95941ea21253b210819c1d4a3863joshualitt u0 = glyph->fAtlasLocation.fX + SK_DistanceFieldInset; 34ddd22d86455d95941ea21253b210819c1d4a3863joshualitt v0 = glyph->fAtlasLocation.fY + SK_DistanceFieldInset; 35ddd22d86455d95941ea21253b210819c1d4a3863joshualitt u1 = u0 + width - 2 * SK_DistanceFieldInset; 36ddd22d86455d95941ea21253b210819c1d4a3863joshualitt v1 = v0 + height - 2 * SK_DistanceFieldInset; 37ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } else { 38ddd22d86455d95941ea21253b210819c1d4a3863joshualitt u0 = glyph->fAtlasLocation.fX; 39ddd22d86455d95941ea21253b210819c1d4a3863joshualitt v0 = glyph->fAtlasLocation.fY; 40ddd22d86455d95941ea21253b210819c1d4a3863joshualitt u1 = u0 + width; 41ddd22d86455d95941ea21253b210819c1d4a3863joshualitt v1 = v0 + height; 42ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 437023a00c35d904e4ccff09c377e9ba26abba6181jvanverth 447023a00c35d904e4ccff09c377e9ba26abba6181jvanverth // normalize 457023a00c35d904e4ccff09c377e9ba26abba6181jvanverth u0 *= 65535; 467023a00c35d904e4ccff09c377e9ba26abba6181jvanverth u0 >>= log2Width; 477023a00c35d904e4ccff09c377e9ba26abba6181jvanverth u1 *= 65535; 487023a00c35d904e4ccff09c377e9ba26abba6181jvanverth u1 >>= log2Width; 497023a00c35d904e4ccff09c377e9ba26abba6181jvanverth v0 *= 65535; 507023a00c35d904e4ccff09c377e9ba26abba6181jvanverth v0 >>= log2Height; 517023a00c35d904e4ccff09c377e9ba26abba6181jvanverth v1 *= 65535; 527023a00c35d904e4ccff09c377e9ba26abba6181jvanverth v1 >>= log2Height; 537023a00c35d904e4ccff09c377e9ba26abba6181jvanverth SkASSERT(u0 >= 0 && u0 <= 65535); 547023a00c35d904e4ccff09c377e9ba26abba6181jvanverth SkASSERT(u1 >= 0 && u1 <= 65535); 557023a00c35d904e4ccff09c377e9ba26abba6181jvanverth SkASSERT(v0 >= 0 && v0 <= 65535); 567023a00c35d904e4ccff09c377e9ba26abba6181jvanverth SkASSERT(v1 >= 0 && v1 <= 65535); 57ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 58ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 59ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // This is a bit wonky, but sometimes we have LCD text, in which case we won't have color 60ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // vertices, hence vertexStride - sizeof(SkIPoint16) 61ddd22d86455d95941ea21253b210819c1d4a3863joshualitt intptr_t colorOffset = sizeof(SkPoint); 62ddd22d86455d95941ea21253b210819c1d4a3863joshualitt intptr_t texCoordOffset = vertexStride - sizeof(SkIPoint16); 63ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 64ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // V0 65ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenPos) { 66ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkPoint* point = reinterpret_cast<SkPoint*>(vertex); 67ddd22d86455d95941ea21253b210819c1d4a3863joshualitt point->fX += transX; 68ddd22d86455d95941ea21253b210819c1d4a3863joshualitt point->fY += transY; 69ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 70ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 71ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenCol) { 72ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); 73ddd22d86455d95941ea21253b210819c1d4a3863joshualitt *vcolor = color; 74ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 75ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 76ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenTexCoords) { 777023a00c35d904e4ccff09c377e9ba26abba6181jvanverth uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); 787023a00c35d904e4ccff09c377e9ba26abba6181jvanverth textureCoords[0] = (uint16_t) u0; 797023a00c35d904e4ccff09c377e9ba26abba6181jvanverth textureCoords[1] = (uint16_t) v0; 80ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 81ddd22d86455d95941ea21253b210819c1d4a3863joshualitt vertex += vertexStride; 82ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 83ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // V1 84ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenPos) { 85ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkPoint* point = reinterpret_cast<SkPoint*>(vertex); 86ddd22d86455d95941ea21253b210819c1d4a3863joshualitt point->fX += transX; 87ddd22d86455d95941ea21253b210819c1d4a3863joshualitt point->fY += transY; 88ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 89ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 90ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenCol) { 91ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); 92ddd22d86455d95941ea21253b210819c1d4a3863joshualitt *vcolor = color; 93ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 94ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 95ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenTexCoords) { 967023a00c35d904e4ccff09c377e9ba26abba6181jvanverth uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); 977023a00c35d904e4ccff09c377e9ba26abba6181jvanverth textureCoords[0] = (uint16_t)u0; 987023a00c35d904e4ccff09c377e9ba26abba6181jvanverth textureCoords[1] = (uint16_t)v1; 99ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 100ddd22d86455d95941ea21253b210819c1d4a3863joshualitt vertex += vertexStride; 101ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 102ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // V2 103ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenPos) { 104ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkPoint* point = reinterpret_cast<SkPoint*>(vertex); 105ddd22d86455d95941ea21253b210819c1d4a3863joshualitt point->fX += transX; 106ddd22d86455d95941ea21253b210819c1d4a3863joshualitt point->fY += transY; 107ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 108ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 109ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenCol) { 110ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); 111ddd22d86455d95941ea21253b210819c1d4a3863joshualitt *vcolor = color; 112ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 113ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 114ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenTexCoords) { 1157023a00c35d904e4ccff09c377e9ba26abba6181jvanverth uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); 1167023a00c35d904e4ccff09c377e9ba26abba6181jvanverth textureCoords[0] = (uint16_t)u1; 1177023a00c35d904e4ccff09c377e9ba26abba6181jvanverth textureCoords[1] = (uint16_t)v1; 118ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 119ddd22d86455d95941ea21253b210819c1d4a3863joshualitt vertex += vertexStride; 120ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 121ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // V3 122ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenPos) { 123ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkPoint* point = reinterpret_cast<SkPoint*>(vertex); 124ddd22d86455d95941ea21253b210819c1d4a3863joshualitt point->fX += transX; 125ddd22d86455d95941ea21253b210819c1d4a3863joshualitt point->fY += transY; 126ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 127ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 128ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenCol) { 129ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkColor* vcolor = reinterpret_cast<SkColor*>(vertex + colorOffset); 130ddd22d86455d95941ea21253b210819c1d4a3863joshualitt *vcolor = color; 131ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 132ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 133ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenTexCoords) { 1347023a00c35d904e4ccff09c377e9ba26abba6181jvanverth uint16_t* textureCoords = reinterpret_cast<uint16_t*>(vertex + texCoordOffset); 1357023a00c35d904e4ccff09c377e9ba26abba6181jvanverth textureCoords[0] = (uint16_t)u1; 1367023a00c35d904e4ccff09c377e9ba26abba6181jvanverth textureCoords[1] = (uint16_t)v0; 137ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 138ddd22d86455d95941ea21253b210819c1d4a3863joshualitt} 139ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 140ddd22d86455d95941ea21253b210819c1d4a3863joshualitttemplate <bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs> 141f856fd1ccdd839646159767f6aa9a2f2a1b97f04Brian Salomonvoid GrAtlasTextBlob::regenInOp(GrDrawOp::Target* target, GrAtlasGlyphCache* fontCache, 142344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon GrBlobRegenHelper* helper, Run* run, Run::SubRunInfo* info, 143344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon SkAutoGlyphCache* lazyCache, int glyphCount, size_t vertexStride, 144344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon GrColor color, SkScalar transX, SkScalar transY) const { 145d1c71fd56c293afb986cb5e7546a3a8e4b190d48bsalomon SkASSERT(lazyCache); 146ddd22d86455d95941ea21253b210819c1d4a3863joshualitt static_assert(!regenGlyphs || regenTexCoords, "must regenTexCoords along regenGlyphs"); 147f856fd1ccdd839646159767f6aa9a2f2a1b97f04Brian Salomon GrAtlasTextStrike* strike = nullptr; 148ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenTexCoords) { 149ddd22d86455d95941ea21253b210819c1d4a3863joshualitt info->resetBulkUseToken(); 150ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 151d1c71fd56c293afb986cb5e7546a3a8e4b190d48bsalomon const SkDescriptor* desc = (run->fOverrideDescriptor && !info->drawAsDistanceFields()) 152d1c71fd56c293afb986cb5e7546a3a8e4b190d48bsalomon ? run->fOverrideDescriptor->getDesc() 153d1c71fd56c293afb986cb5e7546a3a8e4b190d48bsalomon : run->fDescriptor.getDesc(); 154d1c71fd56c293afb986cb5e7546a3a8e4b190d48bsalomon 155d1c71fd56c293afb986cb5e7546a3a8e4b190d48bsalomon if (!*lazyCache || (*lazyCache)->getDescriptor() != *desc) { 1568b6fa5e8a9016ebbf3a03009abc3845b71452550bsalomon SkScalerContextEffects effects; 1578b6fa5e8a9016ebbf3a03009abc3845b71452550bsalomon effects.fPathEffect = run->fPathEffect.get(); 1588b6fa5e8a9016ebbf3a03009abc3845b71452550bsalomon effects.fRasterizer = run->fRasterizer.get(); 1598b6fa5e8a9016ebbf3a03009abc3845b71452550bsalomon effects.fMaskFilter = run->fMaskFilter.get(); 160144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary lazyCache->reset(SkGlyphCache::DetachCache(run->fTypeface.get(), effects, desc)); 161ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 162ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 163ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenGlyphs) { 164d1c71fd56c293afb986cb5e7546a3a8e4b190d48bsalomon strike = fontCache->getStrike(lazyCache->get()); 165ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } else { 166ddd22d86455d95941ea21253b210819c1d4a3863joshualitt strike = info->strike(); 167ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 168ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 169ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 170ddd22d86455d95941ea21253b210819c1d4a3863joshualitt bool brokenRun = false; 171ddd22d86455d95941ea21253b210819c1d4a3863joshualitt for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { 172ddd22d86455d95941ea21253b210819c1d4a3863joshualitt GrGlyph* glyph = nullptr; 1737023a00c35d904e4ccff09c377e9ba26abba6181jvanverth int log2Width = 0, log2Height = 0; 174ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenTexCoords) { 175ddd22d86455d95941ea21253b210819c1d4a3863joshualitt size_t glyphOffset = glyphIdx + info->glyphStartIndex(); 176ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 177ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenGlyphs) { 178ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // Get the id from the old glyph, and use the new strike to lookup 179ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // the glyph. 180ddd22d86455d95941ea21253b210819c1d4a3863joshualitt GrGlyph::PackedID id = fGlyphs[glyphOffset]->fPackedID; 181d1c71fd56c293afb986cb5e7546a3a8e4b190d48bsalomon fGlyphs[glyphOffset] = strike->getGlyph(id, info->maskFormat(), lazyCache->get()); 182ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkASSERT(id == fGlyphs[glyphOffset]->fPackedID); 183ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 184ddd22d86455d95941ea21253b210819c1d4a3863joshualitt glyph = fGlyphs[glyphOffset]; 185ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkASSERT(glyph && glyph->fMaskFormat == info->maskFormat()); 186ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 187ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (!fontCache->hasGlyph(glyph) && 188d1c71fd56c293afb986cb5e7546a3a8e4b190d48bsalomon !strike->addGlyphToAtlas(target, glyph, lazyCache->get(), info->maskFormat())) { 189ddd22d86455d95941ea21253b210819c1d4a3863joshualitt helper->flush(); 190ddd22d86455d95941ea21253b210819c1d4a3863joshualitt brokenRun = glyphIdx > 0; 191ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 192ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(target, 193ddd22d86455d95941ea21253b210819c1d4a3863joshualitt glyph, 194d1c71fd56c293afb986cb5e7546a3a8e4b190d48bsalomon lazyCache->get(), 195ddd22d86455d95941ea21253b210819c1d4a3863joshualitt info->maskFormat()); 196ddd22d86455d95941ea21253b210819c1d4a3863joshualitt SkASSERT(success); 197ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 198ddd22d86455d95941ea21253b210819c1d4a3863joshualitt fontCache->addGlyphToBulkAndSetUseToken(info->bulkUseToken(), glyph, 199342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon target->nextDrawToken()); 2007023a00c35d904e4ccff09c377e9ba26abba6181jvanverth log2Width = fontCache->log2Width(info->maskFormat()); 2017023a00c35d904e4ccff09c377e9ba26abba6181jvanverth log2Height = fontCache->log2Height(info->maskFormat()); 202ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 203ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 204ddd22d86455d95941ea21253b210819c1d4a3863joshualitt intptr_t vertex = reinterpret_cast<intptr_t>(fVertices); 205ddd22d86455d95941ea21253b210819c1d4a3863joshualitt vertex += info->vertexStartIndex(); 206344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon vertex += vertexStride * glyphIdx * GrAtlasTextOp::kVerticesPerGlyph; 207ddd22d86455d95941ea21253b210819c1d4a3863joshualitt regen_vertices<regenPos, regenCol, regenTexCoords>(vertex, glyph, vertexStride, 208ddd22d86455d95941ea21253b210819c1d4a3863joshualitt info->drawAsDistanceFields(), transX, 2097023a00c35d904e4ccff09c377e9ba26abba6181jvanverth transY, log2Width, log2Height, color); 210ddd22d86455d95941ea21253b210819c1d4a3863joshualitt helper->incGlyphCount(); 211ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 212ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 213ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // We may have changed the color so update it here 214ddd22d86455d95941ea21253b210819c1d4a3863joshualitt info->setColor(color); 215ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenTexCoords) { 216ddd22d86455d95941ea21253b210819c1d4a3863joshualitt if (regenGlyphs) { 217ddd22d86455d95941ea21253b210819c1d4a3863joshualitt info->setStrike(strike); 218ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 2192ee084e73056b0ad76b721017f576168b7306da3Brian Salomon info->setAtlasGeneration(brokenRun ? GrDrawOpAtlas::kInvalidAtlasGeneration 2202ee084e73056b0ad76b721017f576168b7306da3Brian Salomon : fontCache->atlasGeneration(info->maskFormat())); 221ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 222ddd22d86455d95941ea21253b210819c1d4a3863joshualitt} 223ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 224ddd22d86455d95941ea21253b210819c1d4a3863joshualittenum RegenMask { 225ddd22d86455d95941ea21253b210819c1d4a3863joshualitt kNoRegen = 0x0, 226ddd22d86455d95941ea21253b210819c1d4a3863joshualitt kRegenPos = 0x1, 227ddd22d86455d95941ea21253b210819c1d4a3863joshualitt kRegenCol = 0x2, 228ddd22d86455d95941ea21253b210819c1d4a3863joshualitt kRegenTex = 0x4, 229ddd22d86455d95941ea21253b210819c1d4a3863joshualitt kRegenGlyph = 0x8 | kRegenTex, // we have to regenerate the texture coords when we regen glyphs 230ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 231ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // combinations 232d1c71fd56c293afb986cb5e7546a3a8e4b190d48bsalomon kRegenPosCol = kRegenPos | kRegenCol, 233ddd22d86455d95941ea21253b210819c1d4a3863joshualitt kRegenPosTex = kRegenPos | kRegenTex, 234ddd22d86455d95941ea21253b210819c1d4a3863joshualitt kRegenPosTexGlyph = kRegenPos | kRegenGlyph, 235ddd22d86455d95941ea21253b210819c1d4a3863joshualitt kRegenPosColTex = kRegenPos | kRegenCol | kRegenTex, 236ddd22d86455d95941ea21253b210819c1d4a3863joshualitt kRegenPosColTexGlyph = kRegenPos | kRegenCol | kRegenGlyph, 237ddd22d86455d95941ea21253b210819c1d4a3863joshualitt kRegenColTex = kRegenCol | kRegenTex, 238ddd22d86455d95941ea21253b210819c1d4a3863joshualitt kRegenColTexGlyph = kRegenCol | kRegenGlyph, 239ddd22d86455d95941ea21253b210819c1d4a3863joshualitt}; 240ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 241d1c71fd56c293afb986cb5e7546a3a8e4b190d48bsalomon#define REGEN_ARGS target, fontCache, helper, &run, &info, lazyCache, \ 242ddd22d86455d95941ea21253b210819c1d4a3863joshualitt *glyphCount, vertexStride, color, transX, transY 243ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 24409d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomonvoid GrAtlasTextBlob::regenInOp(GrDrawOp::Target* target, 24509d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon GrAtlasGlyphCache* fontCache, 24609d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon GrBlobRegenHelper* helper, 24709d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon int runIndex, int subRunIndex, SkAutoGlyphCache* lazyCache, 24809d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon size_t vertexStride, const SkMatrix& viewMatrix, 24909d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon SkScalar x, SkScalar y, GrColor color, 25009d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon void** vertices, size_t* byteCount, int* glyphCount) { 251ddd22d86455d95941ea21253b210819c1d4a3863joshualitt Run& run = fRuns[runIndex]; 252ddd22d86455d95941ea21253b210819c1d4a3863joshualitt Run::SubRunInfo& info = run.fSubRunInfo[subRunIndex]; 253ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 254ddd22d86455d95941ea21253b210819c1d4a3863joshualitt uint64_t currentAtlasGen = fontCache->atlasGeneration(info.maskFormat()); 255ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 2568e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt // Compute translation if any 2578e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt SkScalar transX, transY; 2588e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt info.computeTranslation(viewMatrix, x, y, &transX, &transY); 2598e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt 260f856fd1ccdd839646159767f6aa9a2f2a1b97f04Brian Salomon // Because the GrAtlasGlyphCache may evict the strike a blob depends on using for 261ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // generating its texture coords, we have to track whether or not the strike has 262ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // been abandoned. If it hasn't been abandoned, then we can use the GrGlyph*s as is 263ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // otherwise we have to get the new strike, and use that to get the correct glyphs. 264ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // Because we do not have the packed ids, and thus can't look up our glyphs in the 265ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // new strike, we instead keep our ref to the old strike and use the packed ids from 266ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // it. These ids will still be valid as long as we hold the ref. When we are done 267ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // updating our cache of the GrGlyph*s, we drop our ref on the old strike 268ddd22d86455d95941ea21253b210819c1d4a3863joshualitt bool regenerateGlyphs = info.strike()->isAbandoned(); 269ddd22d86455d95941ea21253b210819c1d4a3863joshualitt bool regenerateTextureCoords = info.atlasGeneration() != currentAtlasGen || 270ddd22d86455d95941ea21253b210819c1d4a3863joshualitt regenerateGlyphs; 271ddd22d86455d95941ea21253b210819c1d4a3863joshualitt bool regenerateColors = kARGB_GrMaskFormat != info.maskFormat() && 272ddd22d86455d95941ea21253b210819c1d4a3863joshualitt info.color() != color; 273ddd22d86455d95941ea21253b210819c1d4a3863joshualitt bool regeneratePositions = transX != 0.f || transY != 0.f; 274ddd22d86455d95941ea21253b210819c1d4a3863joshualitt *glyphCount = info.glyphCount(); 275ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 276ddd22d86455d95941ea21253b210819c1d4a3863joshualitt uint32_t regenMaskBits = kNoRegen; 277ddd22d86455d95941ea21253b210819c1d4a3863joshualitt regenMaskBits |= regeneratePositions ? kRegenPos : 0; 278ddd22d86455d95941ea21253b210819c1d4a3863joshualitt regenMaskBits |= regenerateColors ? kRegenCol : 0; 279ddd22d86455d95941ea21253b210819c1d4a3863joshualitt regenMaskBits |= regenerateTextureCoords ? kRegenTex : 0; 280ddd22d86455d95941ea21253b210819c1d4a3863joshualitt regenMaskBits |= regenerateGlyphs ? kRegenGlyph : 0; 281ddd22d86455d95941ea21253b210819c1d4a3863joshualitt RegenMask regenMask = (RegenMask)regenMaskBits; 282ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 283ddd22d86455d95941ea21253b210819c1d4a3863joshualitt switch (regenMask) { 284344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon case kRegenPos: 285344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon this->regenInOp<true, false, false, false>(REGEN_ARGS); 286344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon break; 287344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon case kRegenCol: 288344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon this->regenInOp<false, true, false, false>(REGEN_ARGS); 289344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon break; 290344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon case kRegenTex: 291344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon this->regenInOp<false, false, true, false>(REGEN_ARGS); 292344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon break; 293344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon case kRegenGlyph: 294344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon this->regenInOp<false, false, true, true>(REGEN_ARGS); 295344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon break; 296344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon 297344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon // combinations 298344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon case kRegenPosCol: 299344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon this->regenInOp<true, true, false, false>(REGEN_ARGS); 300344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon break; 301344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon case kRegenPosTex: 302344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon this->regenInOp<true, false, true, false>(REGEN_ARGS); 303344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon break; 304344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon case kRegenPosTexGlyph: 305344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon this->regenInOp<true, false, true, true>(REGEN_ARGS); 306344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon break; 307344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon case kRegenPosColTex: 308344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon this->regenInOp<true, true, true, false>(REGEN_ARGS); 309344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon break; 310344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon case kRegenPosColTexGlyph: 311344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon this->regenInOp<true, true, true, true>(REGEN_ARGS); 312344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon break; 313344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon case kRegenColTex: 314344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon this->regenInOp<false, true, true, false>(REGEN_ARGS); 315344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon break; 316344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon case kRegenColTexGlyph: 317344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon this->regenInOp<false, true, true, true>(REGEN_ARGS); 318344ec42f60fd9d10f14d4ffaf8e7b7916bb20bccBrian Salomon break; 319ddd22d86455d95941ea21253b210819c1d4a3863joshualitt case kNoRegen: 320ddd22d86455d95941ea21253b210819c1d4a3863joshualitt helper->incGlyphCount(*glyphCount); 321ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 322ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // set use tokens for all of the glyphs in our subrun. This is only valid if we 323ddd22d86455d95941ea21253b210819c1d4a3863joshualitt // have a valid atlas generation 324342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon fontCache->setUseTokenBulk(*info.bulkUseToken(), target->nextDrawToken(), 325ddd22d86455d95941ea21253b210819c1d4a3863joshualitt info.maskFormat()); 326ddd22d86455d95941ea21253b210819c1d4a3863joshualitt break; 327ddd22d86455d95941ea21253b210819c1d4a3863joshualitt } 328ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 329ddd22d86455d95941ea21253b210819c1d4a3863joshualitt *byteCount = info.byteCount(); 330ddd22d86455d95941ea21253b210819c1d4a3863joshualitt *vertices = fVertices + info.vertexStartIndex(); 331ddd22d86455d95941ea21253b210819c1d4a3863joshualitt} 332