1374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt/* 2374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * Copyright 2015 Google Inc. 3374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * 4374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * Use of this source code is governed by a BSD-style license that can be 5374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * found in the LICENSE file. 6374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt */ 7374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt 8374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt#ifndef GrAtlasTextBlob_DEFINED 9374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt#define GrAtlasTextBlob_DEFINED 10374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt 11259fbf191625d504e20c7ede69d988735fc569adjoshualitt#include "GrColor.h" 122ee084e73056b0ad76b721017f576168b7306da3Brian Salomon#include "GrDrawOpAtlas.h" 13c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillips#include "GrGlyphCache.h" 142e2202e95e44bb55a097cb57b020af690ae5cdd6joshualitt#include "GrMemoryPool.h" 156f1d36cc54dc635f5e4d0f925ef79c14914342bbBrian Salomon#include "GrTextUtils.h" 16374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt#include "SkDescriptor.h" 1780747ef591ff3c09c2b610eb21258132d1ff4ef5Mike Reed#include "SkMaskFilterBase.h" 184e97607d9a1cef66fac16f347c5ca813ec4f9515mtklein#include "SkOpts.h" 198b6fa5e8a9016ebbf3a03009abc3845b71452550bsalomon#include "SkPathEffect.h" 205c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon#include "SkPoint3.h" 21274218ef0173ff6046f2258c703c1c83ea37c02fMike Reed#include "SkRectPriv.h" 22259fbf191625d504e20c7ede69d988735fc569adjoshualitt#include "SkSurfaceProps.h" 23374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt#include "SkTInternalLList.h" 24374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt 25c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillipsclass GrAtlasManager; 262e2202e95e44bb55a097cb57b020af690ae5cdd6joshualittstruct GrDistanceFieldAdjustTable; 27c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillipsstruct GrGlyph; 28c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillipsclass GrGlyphCache; 29923037724231f11b9249dbb5bf9688835b5ff9b0joshualittclass GrMemoryPool; 30c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillipsclass GrRestrictedAtlasManager; 31c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillips 322e2202e95e44bb55a097cb57b020af690ae5cdd6joshualittclass SkDrawFilter; 332e2202e95e44bb55a097cb57b020af690ae5cdd6joshualittclass SkTextBlob; 342e2202e95e44bb55a097cb57b020af690ae5cdd6joshualittclass SkTextBlobRunIterator; 352e2202e95e44bb55a097cb57b020af690ae5cdd6joshualitt 36259fbf191625d504e20c7ede69d988735fc569adjoshualitt// With this flag enabled, the GrAtlasTextContext will, as a sanity check, regenerate every blob 37259fbf191625d504e20c7ede69d988735fc569adjoshualitt// that comes in to verify the integrity of its cache 382f2ee83a9c1ff05a94265b175e51c63fc424d554joshualitt#define CACHE_SANITY_CHECK 0 39259fbf191625d504e20c7ede69d988735fc569adjoshualitt 40374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt/* 41374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * A GrAtlasTextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing 42374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * on the GPU. These are initially created with valid positions and colors, but invalid 43374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * texture coordinates. The GrAtlasTextBlob itself has a few Blob-wide properties, and also 44374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * consists of a number of runs. Runs inside a blob are flushed individually so they can be 45374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * reordered. 46374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * 47374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * The only thing(aside from a memcopy) required to flush a GrAtlasTextBlob is to ensure that 48374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * the GrAtlas will not evict anything the Blob needs. 49374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * 50374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * Note: This struct should really be named GrCachedAtasTextBlob, but that is too verbose. 51259fbf191625d504e20c7ede69d988735fc569adjoshualitt * 52259fbf191625d504e20c7ede69d988735fc569adjoshualitt * *WARNING* If you add new fields to this struct, then you may need to to update AssertEqual 53374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt */ 542e2202e95e44bb55a097cb57b020af690ae5cdd6joshualittclass GrAtlasTextBlob : public SkNVRefCnt<GrAtlasTextBlob> { 552e2202e95e44bb55a097cb57b020af690ae5cdd6joshualittpublic: 56374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrAtlasTextBlob); 57374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt 5818923f9a2e83675aecba7561f5095429fb467633Brian Salomon class VertexRegenerator; 5918923f9a2e83675aecba7561f5095429fb467633Brian Salomon 60303cd58870cf1d0d128ff3f37d1dc26778cad5afRobert Phillips static sk_sp<GrAtlasTextBlob> Make(GrMemoryPool*, int glyphCount, int runCount); 61323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 625c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon /** 635c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon * We currently force regeneration of a blob if old or new matrix differ in having perspective. 645c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon * If we ever change that then the key must contain the perspectiveness when there are distance 655c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon * fields as perspective distance field use 3 component vertex positions and non-perspective 665c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon * uses 2. 675c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon */ 68323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt struct Key { 69323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt Key() { 70323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt sk_bzero(this, sizeof(Key)); 71323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 72323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt uint32_t fUniqueID; 73323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // Color may affect the gamma of the mask we generate, but in a fairly limited way. 74323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // Each color is assigned to on of a fixed number of buckets based on its 75323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // luminance. For each luminance bucket there is a "canonical color" that 76323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // represents the bucket. This functionality is currently only supported for A8 77323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt SkColor fCanonicalColor; 78323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt SkPaint::Style fStyle; 79323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt SkPixelGeometry fPixelGeometry; 80323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt bool fHasBlur; 818d7ffcee75661a50ce298dc1b3bc0b76bea018e7brianosman uint32_t fScalerContextFlags; 82323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 83323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt bool operator==(const Key& other) const { 84323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt return 0 == memcmp(this, &other, sizeof(Key)); 85323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 86323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt }; 87323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 88923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt void setupKey(const GrAtlasTextBlob::Key& key, 8980747ef591ff3c09c2b610eb21258132d1ff4ef5Mike Reed const SkMaskFilterBase::BlurRec& blurRec, 90923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt const SkPaint& paint) { 91923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt fKey = key; 92923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt if (key.fHasBlur) { 93923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt fBlurRec = blurRec; 94923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt } 95923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt if (key.fStyle != SkPaint::kFill_Style) { 96923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt fStrokeInfo.fFrameWidth = paint.getStrokeWidth(); 97923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt fStrokeInfo.fMiterLimit = paint.getStrokeMiter(); 98923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt fStrokeInfo.fJoin = paint.getStrokeJoin(); 99923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt } 100923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt } 101923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt 102323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt static const Key& GetKey(const GrAtlasTextBlob& blob) { 103323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt return blob.fKey; 104323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 105323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 106323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt static uint32_t Hash(const Key& key) { 1074e97607d9a1cef66fac16f347c5ca813ec4f9515mtklein return SkOpts::hash(&key, sizeof(Key)); 108323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 109323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 110323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt void operator delete(void* p) { 111323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt GrAtlasTextBlob* blob = reinterpret_cast<GrAtlasTextBlob*>(p); 112303cd58870cf1d0d128ff3f37d1dc26778cad5afRobert Phillips if (blob->fPool) { 113303cd58870cf1d0d128ff3f37d1dc26778cad5afRobert Phillips blob->fPool->release(p); 114303cd58870cf1d0d128ff3f37d1dc26778cad5afRobert Phillips } else { 115303cd58870cf1d0d128ff3f37d1dc26778cad5afRobert Phillips ::operator delete(p); 116303cd58870cf1d0d128ff3f37d1dc26778cad5afRobert Phillips } 117323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 118323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt void* operator new(size_t) { 119b4aab9ae6d27c446af8302b79d15b832c816c633Ben Wagner SK_ABORT("All blobs are created by placement new."); 120323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt return sk_malloc_throw(0); 121323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 122323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 123323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt void* operator new(size_t, void* p) { return p; } 124323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt void operator delete(void* target, void* placement) { 125323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt ::operator delete(target, placement); 126323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 127323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 128323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt bool hasDistanceField() const { return SkToBool(fTextType & kHasDistanceField_TextType); } 129323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt bool hasBitmap() const { return SkToBool(fTextType & kHasBitmap_TextType); } 130323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt void setHasDistanceField() { fTextType |= kHasDistanceField_TextType; } 131323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt void setHasBitmap() { fTextType |= kHasBitmap_TextType; } 132323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 133ddd22d86455d95941ea21253b210819c1d4a3863joshualitt int runCount() const { return fRunCount; } 134ddd22d86455d95941ea21253b210819c1d4a3863joshualitt 135323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt void push_back_run(int currRun) { 136323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt SkASSERT(currRun < fRunCount); 137323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt if (currRun > 0) { 138323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt Run::SubRunInfo& newRun = fRuns[currRun].fSubRunInfo.back(); 139323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt Run::SubRunInfo& lastRun = fRuns[currRun - 1].fSubRunInfo.back(); 140323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt newRun.setAsSuccessor(lastRun); 141323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 142323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 143323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 144323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // sets the last subrun of runIndex to use distance field text 1455c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon void setSubRunHasDistanceFields(int runIndex, bool hasLCD, bool isAntiAlias, bool hasWCoord) { 146323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt Run& run = fRuns[runIndex]; 147323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt Run::SubRunInfo& subRun = run.fSubRunInfo.back(); 148323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt subRun.setUseLCDText(hasLCD); 14990e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth subRun.setAntiAliased(isAntiAlias); 150323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt subRun.setDrawAsDistanceFields(); 1515c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon subRun.setHasWCoord(hasWCoord); 152323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 153323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 15454d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth void setRunPaintFlags(int runIndex, uint16_t paintFlags) { 15554d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth fRuns[runIndex].fPaintFlags = paintFlags & Run::kPaintFlagsMask; 15689737decb4965ec250f02af432884366945d2e53Jim Van Verth } 15789737decb4965ec250f02af432884366945d2e53Jim Van Verth 158323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt void setMinAndMaxScale(SkScalar scaledMax, SkScalar scaledMin) { 159323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // we init fMaxMinScale and fMinMaxScale in the constructor 160323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt fMaxMinScale = SkMaxScalar(scaledMax, fMaxMinScale); 161323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt fMinMaxScale = SkMinScalar(scaledMin, fMinMaxScale); 162323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 163323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 164323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // inits the override descriptor on the current run. All following subruns must use this 165323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // descriptor 166323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt void initOverride(int runIndex) { 167323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt Run& run = fRuns[runIndex]; 168323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // Push back a new subrun to fill and set the override descriptor 169323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt run.push_back(); 170323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt run.fOverrideDescriptor.reset(new SkAutoDescriptor); 171323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 172323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 173323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt SkGlyphCache* setupCache(int runIndex, 174323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt const SkSurfaceProps& props, 175d8327a8c8bad870112b574c4533270370f5c1ccfHerb Derby SkScalerContextFlags scalerContextFlags, 176323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt const SkPaint& skPaint, 177f6d1e605317917146362706ed460b5ed6624fcc5bungeman const SkMatrix* viewMatrix); 178323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 179323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // Appends a glyph to the blob. If the glyph is too large, the glyph will be appended 180323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // as a path. 181323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt void appendGlyph(int runIndex, 182323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt const SkRect& positions, 183323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt GrColor color, 184caf1ebb95f7fea81d416b81beb4b46c25643c714Robert Phillips sk_sp<GrTextStrike> strike, 185323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt GrGlyph* glyph, 186c2878e23d405e7ae77f6110602ad75ce1f6b941cbsalomon SkGlyphCache*, const SkGlyph& skGlyph, 18754d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth SkScalar x, SkScalar y, SkScalar scale, bool preTransformed); 18854d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth 18954d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth // Appends a glyph to the blob as a path only. 19054d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth void appendPathGlyph(int runIndex, const SkPath& path, 19154d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth SkScalar x, SkScalar y, SkScalar scale, bool preTransformed); 192323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 1935c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon static size_t GetVertexStride(GrMaskFormat maskFormat, bool isDistanceFieldWithWCoord) { 194323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt switch (maskFormat) { 195323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt case kA8_GrMaskFormat: 1965c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon return isDistanceFieldWithWCoord ? kGrayTextDFPerspectiveVASize : kGrayTextVASize; 197323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt case kARGB_GrMaskFormat: 1985c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon SkASSERT(!isDistanceFieldWithWCoord); 199323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt return kColorTextVASize; 200323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt default: 2015c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon SkASSERT(!isDistanceFieldWithWCoord); 202323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt return kLCDTextVASize; 203323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 204323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 205323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 20680747ef591ff3c09c2b610eb21258132d1ff4ef5Mike Reed bool mustRegenerate(const GrTextUtils::Paint&, const SkMaskFilterBase::BlurRec& blurRec, 207323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt const SkMatrix& viewMatrix, SkScalar x, SkScalar y); 208323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 209c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillips void flush(GrRestrictedAtlasManager*, GrTextUtils::Target*, const SkSurfaceProps& props, 21054d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth const GrDistanceFieldAdjustTable* distanceAdjustTable, 21154d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth const GrTextUtils::Paint& paint, const GrClip& clip, 21254d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, 21354d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth SkScalar y); 214323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 2158e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt void computeSubRunBounds(SkRect* outBounds, int runIndex, int subRunIndex, 2168e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { 217bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt // We don't yet position distance field text on the cpu, so we have to map the vertex bounds 218bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt // into device space. 219bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt // We handle vertex bounds differently for distance field text and bitmap text because 220bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt // the vertex bounds of bitmap text are in device space. If we are flushing multiple runs 221bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt // from one blob then we are going to pay the price here of mapping the rect for each run. 222bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt const Run& run = fRuns[runIndex]; 223bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt const Run::SubRunInfo& subRun = run.fSubRunInfo[subRunIndex]; 224bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt *outBounds = subRun.vertexBounds(); 225bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt if (subRun.drawAsDistanceFields()) { 226bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt // Distance field text is positioned with the (X,Y) as part of the glyph position, 227bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt // and currently the view matrix is applied on the GPU 2288e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt outBounds->offset(x - fInitialX, y - fInitialY); 2298e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt viewMatrix.mapRect(outBounds); 230bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt } else { 231bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt // Bitmap text is fully positioned on the CPU, and offset by an (X,Y) translate in 232bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt // device space. 233bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt SkMatrix boundsMatrix = fInitialViewMatrixInverse; 234bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt 235bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt boundsMatrix.postTranslate(-fInitialX, -fInitialY); 236bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt 2378e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt boundsMatrix.postTranslate(x, y); 238bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt 2398e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt boundsMatrix.postConcat(viewMatrix); 240bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt boundsMatrix.mapRect(outBounds); 241bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt 242bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt // Due to floating point numerical inaccuracies, we have to round out here 243bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt outBounds->roundOut(outBounds); 244bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt } 245bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt } 246bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt 247323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // position + local coord 248323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt static const size_t kColorTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16); 249323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt static const size_t kGrayTextVASize = sizeof(SkPoint) + sizeof(GrColor) + sizeof(SkIPoint16); 2505c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon static const size_t kGrayTextDFPerspectiveVASize = 2515c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon sizeof(SkPoint3) + sizeof(GrColor) + sizeof(SkIPoint16); 252323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt static const size_t kLCDTextVASize = kGrayTextVASize; 2535c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon static const size_t kMaxVASize = kGrayTextDFPerspectiveVASize; 254323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt static const int kVerticesPerGlyph = 4; 255323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 256323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt static void AssertEqual(const GrAtlasTextBlob&, const GrAtlasTextBlob&); 257323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 258323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // The color here is the GrPaint color, and it is used to determine whether we 259323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // have to regenerate LCD text blobs. 260323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt // We use this color vs the SkPaint color because it has the colorfilter applied. 26158c3cce1144f83bc7e4ee5e93931b8721560735bJim Van Verth void initReusableBlob(SkColor luminanceColor, const SkMatrix& viewMatrix, 26258c3cce1144f83bc7e4ee5e93931b8721560735bJim Van Verth SkScalar x, SkScalar y) { 263bc2cdd154bf5a031ca9d3a530123d9f7a4c0925dJim Van Verth fLuminanceColor = luminanceColor; 2647481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt this->setupViewMatrix(viewMatrix, x, y); 265323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 266323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 2677481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt void initThrowawayBlob(const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { 2687481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt this->setupViewMatrix(viewMatrix, x, y); 269323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt } 270323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 271923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt const Key& key() const { return fKey; } 272923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt 273923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt ~GrAtlasTextBlob() { 274923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt for (int i = 0; i < fRunCount; i++) { 275923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt fRuns[i].~Run(); 276923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt } 277923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt } 278923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt 279bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt //////////////////////////////////////////////////////////////////////////////////////////////// 280bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt // Internal test methods 28156c37143830d8318853663bf2bcd5bc99c960a75Jim Van Verth std::unique_ptr<GrDrawOp> test_makeOp(int glyphCount, uint16_t run, uint16_t subRun, 28244acb5b09bb87163bc9c010be915b3f33e3157ebBrian Salomon const SkMatrix& viewMatrix, SkScalar x, SkScalar y, 28344acb5b09bb87163bc9c010be915b3f33e3157ebBrian Salomon const GrTextUtils::Paint&, const SkSurfaceProps&, 284c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillips const GrDistanceFieldAdjustTable*, 285c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillips GrRestrictedAtlasManager*, GrTextUtils::Target*); 286bc81111f246ce2d5fbb61d7a347c9d890f6c8359joshualitt 287323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualittprivate: 288923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt GrAtlasTextBlob() 289923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt : fMaxMinScale(-SK_ScalarMax) 290923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt , fMinMaxScale(SK_ScalarMax) 291923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt , fTextType(0) {} 292923037724231f11b9249dbb5bf9688835b5ff9b0joshualitt 293323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 2948e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt // This function will only be called when we are generating a blob from scratch. We record the 2957481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt // initial view matrix and initial offsets(x,y), because we record vertex bounds relative to 2967481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt // these numbers. When blobs are reused with new matrices, we need to return to model space so 2977481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt // we can update the vertex bounds appropriately. 2987481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt void setupViewMatrix(const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { 2998e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt fInitialViewMatrix = viewMatrix; 3007481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt if (!viewMatrix.invert(&fInitialViewMatrixInverse)) { 3017481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt fInitialViewMatrixInverse = SkMatrix::I(); 3027481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt SkDebugf("Could not invert viewmatrix\n"); 3037481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt } 3048e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt fInitialX = x; 3058e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt fInitialY = y; 3068e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt 3078e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt // make sure all initial subruns have the correct VM and X/Y applied 3088e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt for (int i = 0; i < fRunCount; i++) { 3098e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt fRuns[i].fSubRunInfo[0].init(fInitialViewMatrix, x, y); 3108e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt } 3117481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt } 3127481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt 313374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt /* 314374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * Each Run inside of the blob can have its texture coordinates regenerated if required. 315374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * To determine if regeneration is necessary, fAtlasGeneration is used. If there have been 316374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * any evictions inside of the atlas, then we will simply regenerate Runs. We could track 317374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * this at a more fine grained level, but its not clear if this is worth it, as evictions 318374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * should be fairly rare. 319374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * 320374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * One additional point, each run can contain glyphs with any of the three mask formats. 321374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * We call these SubRuns. Because a subrun must be a contiguous range, we have to create 322374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * a new subrun each time the mask format changes in a run. In theory, a run can have as 323374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * many SubRuns as it has glyphs, ie if a run alternates between color emoji and A8. In 324374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * practice, the vast majority of runs have only a single subrun. 325374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * 326374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * Finally, for runs where the entire thing is too large for the GrAtlasTextContext to 327f4c13166de2ad3c67a4a391d8595b5c8fa04ad4dJim Van Verth * handle, we have a bit to mark the run as flushable via rendering as paths or as scaled 328f4c13166de2ad3c67a4a391d8595b5c8fa04ad4dJim Van Verth * glyphs. It would be a bit expensive to figure out ahead of time whether or not a run 329374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * can flush in this manner, so we always allocate vertices for the run, regardless of 330374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * whether or not it is too large. The benefit of this strategy is that we can always reuse 331374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * a blob allocation regardless of viewmatrix changes. We could store positions for these 332f4c13166de2ad3c67a4a391d8595b5c8fa04ad4dJim Van Verth * glyphs, however, it's not clear if this is a win because we'd still have to either go to the 333374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * glyph cache to get the path at flush time, or hold onto the path in the cache, which 334374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt * would greatly increase the memory of these cached items. 335374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt */ 336374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt struct Run { 33754d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth Run() : fPaintFlags(0) 33854d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth , fInitialized(false) { 339374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt // To ensure we always have one subrun, we push back a fresh run here 340374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt fSubRunInfo.push_back(); 341374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt } 342374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt struct SubRunInfo { 343374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt SubRunInfo() 3442ee084e73056b0ad76b721017f576168b7306da3Brian Salomon : fAtlasGeneration(GrDrawOpAtlas::kInvalidAtlasGeneration) 3452ee084e73056b0ad76b721017f576168b7306da3Brian Salomon , fVertexStartIndex(0) 3462ee084e73056b0ad76b721017f576168b7306da3Brian Salomon , fVertexEndIndex(0) 3472ee084e73056b0ad76b721017f576168b7306da3Brian Salomon , fGlyphStartIndex(0) 3482ee084e73056b0ad76b721017f576168b7306da3Brian Salomon , fGlyphEndIndex(0) 3492ee084e73056b0ad76b721017f576168b7306da3Brian Salomon , fColor(GrColor_ILLEGAL) 3502ee084e73056b0ad76b721017f576168b7306da3Brian Salomon , fMaskFormat(kA8_GrMaskFormat) 35190e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth , fFlags(0) { 352274218ef0173ff6046f2258c703c1c83ea37c02fMike Reed fVertexBounds = SkRectPriv::MakeLargestInverted(); 3537481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt } 3547e97b0bad0d80901a19922323343a19d69f34b0bjoshualitt SubRunInfo(const SubRunInfo& that) 3557e97b0bad0d80901a19922323343a19d69f34b0bjoshualitt : fBulkUseToken(that.fBulkUseToken) 3567e97b0bad0d80901a19922323343a19d69f34b0bjoshualitt , fStrike(SkSafeRef(that.fStrike.get())) 3578e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt , fCurrentViewMatrix(that.fCurrentViewMatrix) 3587481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt , fVertexBounds(that.fVertexBounds) 3597e97b0bad0d80901a19922323343a19d69f34b0bjoshualitt , fAtlasGeneration(that.fAtlasGeneration) 3607e97b0bad0d80901a19922323343a19d69f34b0bjoshualitt , fVertexStartIndex(that.fVertexStartIndex) 3617e97b0bad0d80901a19922323343a19d69f34b0bjoshualitt , fVertexEndIndex(that.fVertexEndIndex) 3627e97b0bad0d80901a19922323343a19d69f34b0bjoshualitt , fGlyphStartIndex(that.fGlyphStartIndex) 3637e97b0bad0d80901a19922323343a19d69f34b0bjoshualitt , fGlyphEndIndex(that.fGlyphEndIndex) 3648e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt , fX(that.fX) 3658e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt , fY(that.fY) 366f9e658b1d648948ebe37db5cceebd61cddc94575joshualitt , fColor(that.fColor) 3677e97b0bad0d80901a19922323343a19d69f34b0bjoshualitt , fMaskFormat(that.fMaskFormat) 36890e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth , fFlags(that.fFlags) { 3697e97b0bad0d80901a19922323343a19d69f34b0bjoshualitt } 3703660d534516e4687546a43ac80d0ae40bc68dae7joshualitt 37118b072dbcb2df81945b87449b591c4b244e7fa37joshualitt // TODO when this object is more internal, drop the privacy 3723660d534516e4687546a43ac80d0ae40bc68dae7joshualitt void resetBulkUseToken() { fBulkUseToken.reset(); } 3732ee084e73056b0ad76b721017f576168b7306da3Brian Salomon GrDrawOpAtlas::BulkUseTokenUpdater* bulkUseToken() { return &fBulkUseToken; } 374caf1ebb95f7fea81d416b81beb4b46c25643c714Robert Phillips void setStrike(sk_sp<GrTextStrike> strike) { fStrike = std::move(strike); } 375caf1ebb95f7fea81d416b81beb4b46c25643c714Robert Phillips GrTextStrike* strike() const { return fStrike.get(); } 376caf1ebb95f7fea81d416b81beb4b46c25643c714Robert Phillips sk_sp<GrTextStrike> refStrike() const { return fStrike; } 3773660d534516e4687546a43ac80d0ae40bc68dae7joshualitt 3783660d534516e4687546a43ac80d0ae40bc68dae7joshualitt void setAtlasGeneration(uint64_t atlasGeneration) { fAtlasGeneration = atlasGeneration;} 3793660d534516e4687546a43ac80d0ae40bc68dae7joshualitt uint64_t atlasGeneration() const { return fAtlasGeneration; } 3803660d534516e4687546a43ac80d0ae40bc68dae7joshualitt 3813660d534516e4687546a43ac80d0ae40bc68dae7joshualitt size_t byteCount() const { return fVertexEndIndex - fVertexStartIndex; } 3823660d534516e4687546a43ac80d0ae40bc68dae7joshualitt size_t vertexStartIndex() const { return fVertexStartIndex; } 3833660d534516e4687546a43ac80d0ae40bc68dae7joshualitt size_t vertexEndIndex() const { return fVertexEndIndex; } 3843660d534516e4687546a43ac80d0ae40bc68dae7joshualitt void appendVertices(size_t vertexStride) { 3853660d534516e4687546a43ac80d0ae40bc68dae7joshualitt fVertexEndIndex += vertexStride * kVerticesPerGlyph; 3863660d534516e4687546a43ac80d0ae40bc68dae7joshualitt } 3873660d534516e4687546a43ac80d0ae40bc68dae7joshualitt 3883660d534516e4687546a43ac80d0ae40bc68dae7joshualitt uint32_t glyphCount() const { return fGlyphEndIndex - fGlyphStartIndex; } 3893660d534516e4687546a43ac80d0ae40bc68dae7joshualitt uint32_t glyphStartIndex() const { return fGlyphStartIndex; } 3903660d534516e4687546a43ac80d0ae40bc68dae7joshualitt uint32_t glyphEndIndex() const { return fGlyphEndIndex; } 3913660d534516e4687546a43ac80d0ae40bc68dae7joshualitt void glyphAppended() { fGlyphEndIndex++; } 392f9e658b1d648948ebe37db5cceebd61cddc94575joshualitt void setColor(GrColor color) { fColor = color; } 393f9e658b1d648948ebe37db5cceebd61cddc94575joshualitt GrColor color() const { return fColor; } 3943660d534516e4687546a43ac80d0ae40bc68dae7joshualitt void setMaskFormat(GrMaskFormat format) { fMaskFormat = format; } 3953660d534516e4687546a43ac80d0ae40bc68dae7joshualitt GrMaskFormat maskFormat() const { return fMaskFormat; } 3963660d534516e4687546a43ac80d0ae40bc68dae7joshualitt 39718b072dbcb2df81945b87449b591c4b244e7fa37joshualitt void setAsSuccessor(const SubRunInfo& prev) { 39818b072dbcb2df81945b87449b591c4b244e7fa37joshualitt fGlyphStartIndex = prev.glyphEndIndex(); 39918b072dbcb2df81945b87449b591c4b244e7fa37joshualitt fGlyphEndIndex = prev.glyphEndIndex(); 40018b072dbcb2df81945b87449b591c4b244e7fa37joshualitt 40118b072dbcb2df81945b87449b591c4b244e7fa37joshualitt fVertexStartIndex = prev.vertexEndIndex(); 40218b072dbcb2df81945b87449b591c4b244e7fa37joshualitt fVertexEndIndex = prev.vertexEndIndex(); 4038e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt 4048e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt // copy over viewmatrix settings 4058e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt this->init(prev.fCurrentViewMatrix, prev.fX, prev.fY); 40618b072dbcb2df81945b87449b591c4b244e7fa37joshualitt } 40718b072dbcb2df81945b87449b591c4b244e7fa37joshualitt 4087481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt const SkRect& vertexBounds() const { return fVertexBounds; } 4097481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt void joinGlyphBounds(const SkRect& glyphBounds) { 4107481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt fVertexBounds.joinNonEmptyArg(glyphBounds); 4117481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt } 4127481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt 4138e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt void init(const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { 4148e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt fCurrentViewMatrix = viewMatrix; 4158e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt fX = x; 4168e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt fY = y; 4178e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt } 4188e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt 4198e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt // This function assumes the translation will be applied before it is called again 4208e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt void computeTranslation(const SkMatrix& viewMatrix, SkScalar x, SkScalar y, 4215c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon SkScalar* transX, SkScalar* transY); 4228e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt 4233660d534516e4687546a43ac80d0ae40bc68dae7joshualitt // df properties 42490e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth void setDrawAsDistanceFields() { fFlags |= kDrawAsSDF_Flag; } 42590e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth bool drawAsDistanceFields() const { return SkToBool(fFlags & kDrawAsSDF_Flag); } 42690e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth void setUseLCDText(bool useLCDText) { 42790e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth fFlags = useLCDText ? fFlags | kUseLCDText_Flag : fFlags & ~kUseLCDText_Flag; 42890e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth } 42990e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth bool hasUseLCDText() const { return SkToBool(fFlags & kUseLCDText_Flag); } 43090e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth void setAntiAliased(bool antiAliased) { 43190e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth fFlags = antiAliased ? fFlags | kAntiAliased_Flag : fFlags & ~kAntiAliased_Flag; 43290e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth } 43390e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth bool isAntiAliased() const { return SkToBool(fFlags & kAntiAliased_Flag); } 4345c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon void setHasWCoord(bool hasW) { 4355c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon fFlags = hasW ? (fFlags | kHasWCoord_Flag) : fFlags & ~kHasWCoord_Flag; 4365c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon } 4375c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon bool hasWCoord() const { return SkToBool(fFlags & kHasWCoord_Flag); } 4383660d534516e4687546a43ac80d0ae40bc68dae7joshualitt 4393660d534516e4687546a43ac80d0ae40bc68dae7joshualitt private: 44090e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth enum Flag { 44190e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth kDrawAsSDF_Flag = 0x1, 44290e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth kUseLCDText_Flag = 0x2, 4435c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon kAntiAliased_Flag = 0x4, 4445c6ac64516bb56bbdb5d7aedee1a348acc16e29bBrian Salomon kHasWCoord_Flag = 0x8 44590e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth }; 44690e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth 4472ee084e73056b0ad76b721017f576168b7306da3Brian Salomon GrDrawOpAtlas::BulkUseTokenUpdater fBulkUseToken; 448caf1ebb95f7fea81d416b81beb4b46c25643c714Robert Phillips sk_sp<GrTextStrike> fStrike; 4498e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt SkMatrix fCurrentViewMatrix; 4507481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt SkRect fVertexBounds; 451374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt uint64_t fAtlasGeneration; 452374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt size_t fVertexStartIndex; 453374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt size_t fVertexEndIndex; 454374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt uint32_t fGlyphStartIndex; 455374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt uint32_t fGlyphEndIndex; 4568e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt SkScalar fX; 4578e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt SkScalar fY; 458f9e658b1d648948ebe37db5cceebd61cddc94575joshualitt GrColor fColor; 459374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt GrMaskFormat fMaskFormat; 46090e89b366a7dc90111c861ba76c492ce1743a0d1Jim Van Verth uint32_t fFlags; 46158c3cce1144f83bc7e4ee5e93931b8721560735bJim Van Verth }; // SubRunInfo 462374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt 463374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt SubRunInfo& push_back() { 464374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt // Forward glyph / vertex information to seed the new sub run 465374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt SubRunInfo& newSubRun = fSubRunInfo.push_back(); 46618b072dbcb2df81945b87449b591c4b244e7fa37joshualitt const SubRunInfo& prevSubRun = fSubRunInfo.fromBack(1); 467374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt 46818b072dbcb2df81945b87449b591c4b244e7fa37joshualitt newSubRun.setAsSuccessor(prevSubRun); 469374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt return newSubRun; 470374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt } 471374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt static const int kMinSubRuns = 1; 472144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary sk_sp<SkTypeface> fTypeface; 473374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt SkSTArray<kMinSubRuns, SubRunInfo> fSubRunInfo; 474374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt SkAutoDescriptor fDescriptor; 4758b6fa5e8a9016ebbf3a03009abc3845b71452550bsalomon 4768b6fa5e8a9016ebbf3a03009abc3845b71452550bsalomon // Effects from the paint that are used to build a SkScalerContext. 4778b6fa5e8a9016ebbf3a03009abc3845b71452550bsalomon sk_sp<SkPathEffect> fPathEffect; 4788b6fa5e8a9016ebbf3a03009abc3845b71452550bsalomon sk_sp<SkMaskFilter> fMaskFilter; 4793660d534516e4687546a43ac80d0ae40bc68dae7joshualitt 4803660d534516e4687546a43ac80d0ae40bc68dae7joshualitt // Distance field text cannot draw coloremoji, and so has to fall back. However, 4813660d534516e4687546a43ac80d0ae40bc68dae7joshualitt // though the distance field text and the coloremoji may share the same run, they 4823660d534516e4687546a43ac80d0ae40bc68dae7joshualitt // will have different descriptors. If fOverrideDescriptor is non-nullptr, then it 4833660d534516e4687546a43ac80d0ae40bc68dae7joshualitt // will be used in place of the run's descriptor to regen texture coords 484145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner std::unique_ptr<SkAutoDescriptor> fOverrideDescriptor; // df properties 48554d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth 48654d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth // Any glyphs that can't be rendered with the base or override descriptor 48754d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth // are rendered as paths 48854d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth struct PathGlyph { 48954d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth PathGlyph(const SkPath& path, SkScalar x, SkScalar y, SkScalar scale, bool preXformed) 49054d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth : fPath(path) 49154d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth , fX(x) 49254d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth , fY(y) 49354d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth , fScale(scale) 49454d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth , fPreTransformed(preXformed) {} 49554d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth SkPath fPath; 49654d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth SkScalar fX; 49754d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth SkScalar fY; 49854d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth SkScalar fScale; 49954d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth bool fPreTransformed; 50054d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth }; 50154d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth 50254d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth SkTArray<PathGlyph> fPathGlyphs; 50354d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth 50454d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth struct { 50554d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth unsigned fPaintFlags : 16; // needed mainly for rendering paths 50654d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth bool fInitialized : 1; 50754d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth }; 50854d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth // the only flags we need to set 50954d9c889fb6aca043a7b005d61de4e0e65a3ae53Jim Van Verth static constexpr auto kPaintFlagsMask = SkPaint::kAntiAlias_Flag; 51058c3cce1144f83bc7e4ee5e93931b8721560735bJim Van Verth }; // Run 511374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt 512f18b1d88aa98f81d2c115a59d887265fea63f876Brian Salomon inline std::unique_ptr<GrAtlasTextOp> makeOp( 51356c37143830d8318853663bf2bcd5bc99c960a75Jim Van Verth const Run::SubRunInfo& info, int glyphCount, uint16_t run, uint16_t subRun, 514f18b1d88aa98f81d2c115a59d887265fea63f876Brian Salomon const SkMatrix& viewMatrix, SkScalar x, SkScalar y, const SkIRect& clipRect, 515c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillips const GrTextUtils::Paint&, const SkSurfaceProps&, 516c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillips const GrDistanceFieldAdjustTable*, GrRestrictedAtlasManager* , GrTextUtils::Target*); 517323c2ebe9e171d399c922f1efb5b6a2ca9d56b2ejoshualitt 518374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt struct StrokeInfo { 519374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt SkScalar fFrameWidth; 520374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt SkScalar fMiterLimit; 521374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt SkPaint::Join fJoin; 522374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt }; 523374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt 524374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt enum TextType { 525374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt kHasDistanceField_TextType = 0x1, 526374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt kHasBitmap_TextType = 0x2, 527374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt }; 528374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt 529374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt // all glyph / vertex offsets are into these pools. 53018923f9a2e83675aecba7561f5095429fb467633Brian Salomon char* fVertices; 531374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt GrGlyph** fGlyphs; 532374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt Run* fRuns; 533303cd58870cf1d0d128ff3f37d1dc26778cad5afRobert Phillips GrMemoryPool* fPool; // this will be null when DDLs are being recorded 53480747ef591ff3c09c2b610eb21258132d1ff4ef5Mike Reed SkMaskFilterBase::BlurRec fBlurRec; 535374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt StrokeInfo fStrokeInfo; 536374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt Key fKey; 5378e0ef294d0fc310432308dc09b8a48a53f7aabc1joshualitt SkMatrix fInitialViewMatrix; 5387481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt SkMatrix fInitialViewMatrixInverse; 5392f2ee83a9c1ff05a94265b175e51c63fc424d554joshualitt size_t fSize; 540bc2cdd154bf5a031ca9d3a530123d9f7a4c0925dJim Van Verth SkColor fLuminanceColor; 5417481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt SkScalar fInitialX; 5427481e75830dfae1e9084ff62e3d8438879e31aaajoshualitt SkScalar fInitialY; 543374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt 544374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt // We can reuse distance field text, but only if the new viewmatrix would not result in 545374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt // a mip change. Because there can be multiple runs in a blob, we track the overall 546374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt // maximum minimum scale, and minimum maximum scale, we can support before we need to regen 547374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt SkScalar fMaxMinScale; 548374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt SkScalar fMinMaxScale; 549374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt int fRunCount; 550374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt uint8_t fTextType; 551374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt}; 552374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt 55318923f9a2e83675aecba7561f5095429fb467633Brian Salomon/** 55418923f9a2e83675aecba7561f5095429fb467633Brian Salomon * Used to produce vertices for a subrun of a blob. The vertices are cached in the blob itself. 55518923f9a2e83675aecba7561f5095429fb467633Brian Salomon * This is invoked each time a sub run is drawn. It regenerates the vertex data as required either 55618923f9a2e83675aecba7561f5095429fb467633Brian Salomon * because of changes to the atlas or because of different draw parameters (e.g. color change). In 55718923f9a2e83675aecba7561f5095429fb467633Brian Salomon * rare cases the draw may have to interrupted and flushed in the middle of the sub run in order to 55818923f9a2e83675aecba7561f5095429fb467633Brian Salomon * free up atlas space. Thus, this generator is stateful and should be invoked in a loop until the 55918923f9a2e83675aecba7561f5095429fb467633Brian Salomon * entire sub run has been completed. 56018923f9a2e83675aecba7561f5095429fb467633Brian Salomon */ 56118923f9a2e83675aecba7561f5095429fb467633Brian Salomonclass GrAtlasTextBlob::VertexRegenerator { 56218923f9a2e83675aecba7561f5095429fb467633Brian Salomonpublic: 56318923f9a2e83675aecba7561f5095429fb467633Brian Salomon /** 56418923f9a2e83675aecba7561f5095429fb467633Brian Salomon * Consecutive VertexRegenerators often use the same SkGlyphCache. If the same instance of 56518923f9a2e83675aecba7561f5095429fb467633Brian Salomon * SkAutoGlyphCache is reused then it can save the cost of multiple detach/attach operations of 56618923f9a2e83675aecba7561f5095429fb467633Brian Salomon * SkGlyphCache. 56718923f9a2e83675aecba7561f5095429fb467633Brian Salomon */ 5684bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips VertexRegenerator(GrResourceProvider*, GrAtlasTextBlob*, int runIdx, int subRunIdx, 5694bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips const SkMatrix& viewMatrix, SkScalar x, SkScalar y, GrColor color, 570c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillips GrDeferredUploadTarget*, GrGlyphCache*, GrAtlasManager*, 571c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillips SkAutoGlyphCache*); 57218923f9a2e83675aecba7561f5095429fb467633Brian Salomon 57318923f9a2e83675aecba7561f5095429fb467633Brian Salomon struct Result { 57418923f9a2e83675aecba7561f5095429fb467633Brian Salomon /** 57518923f9a2e83675aecba7561f5095429fb467633Brian Salomon * Was regenerate() able to draw all the glyphs from the sub run? If not flush all glyph 57618923f9a2e83675aecba7561f5095429fb467633Brian Salomon * draws and call regenerate() again. 57718923f9a2e83675aecba7561f5095429fb467633Brian Salomon */ 57818923f9a2e83675aecba7561f5095429fb467633Brian Salomon bool fFinished = true; 57918923f9a2e83675aecba7561f5095429fb467633Brian Salomon 58018923f9a2e83675aecba7561f5095429fb467633Brian Salomon /** 58118923f9a2e83675aecba7561f5095429fb467633Brian Salomon * How many glyphs were regenerated. Will be equal to the sub run's glyph count if 58218923f9a2e83675aecba7561f5095429fb467633Brian Salomon * fType is kFinished. 58318923f9a2e83675aecba7561f5095429fb467633Brian Salomon */ 58418923f9a2e83675aecba7561f5095429fb467633Brian Salomon int fGlyphsRegenerated = 0; 58518923f9a2e83675aecba7561f5095429fb467633Brian Salomon 58618923f9a2e83675aecba7561f5095429fb467633Brian Salomon /** 58718923f9a2e83675aecba7561f5095429fb467633Brian Salomon * Pointer where the caller finds the first regenerated vertex. 58818923f9a2e83675aecba7561f5095429fb467633Brian Salomon */ 58918923f9a2e83675aecba7561f5095429fb467633Brian Salomon const char* fFirstVertex; 59018923f9a2e83675aecba7561f5095429fb467633Brian Salomon }; 59118923f9a2e83675aecba7561f5095429fb467633Brian Salomon 59218923f9a2e83675aecba7561f5095429fb467633Brian Salomon Result regenerate(); 59318923f9a2e83675aecba7561f5095429fb467633Brian Salomon 59418923f9a2e83675aecba7561f5095429fb467633Brian Salomonprivate: 59518923f9a2e83675aecba7561f5095429fb467633Brian Salomon template <bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs> 59618923f9a2e83675aecba7561f5095429fb467633Brian Salomon Result doRegen(); 59718923f9a2e83675aecba7561f5095429fb467633Brian Salomon 5984bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips GrResourceProvider* fResourceProvider; 59918923f9a2e83675aecba7561f5095429fb467633Brian Salomon const SkMatrix& fViewMatrix; 60018923f9a2e83675aecba7561f5095429fb467633Brian Salomon GrAtlasTextBlob* fBlob; 60118923f9a2e83675aecba7561f5095429fb467633Brian Salomon GrDeferredUploadTarget* fUploadTarget; 602c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillips GrGlyphCache* fGlyphCache; 603c4039ea466d39ede0ea44fc7a18f1174f893f11dRobert Phillips GrAtlasManager* fFullAtlasManager; 60418923f9a2e83675aecba7561f5095429fb467633Brian Salomon SkAutoGlyphCache* fLazyCache; 60518923f9a2e83675aecba7561f5095429fb467633Brian Salomon Run* fRun; 60618923f9a2e83675aecba7561f5095429fb467633Brian Salomon Run::SubRunInfo* fSubRun; 60718923f9a2e83675aecba7561f5095429fb467633Brian Salomon GrColor fColor; 60818923f9a2e83675aecba7561f5095429fb467633Brian Salomon SkScalar fTransX; 60918923f9a2e83675aecba7561f5095429fb467633Brian Salomon SkScalar fTransY; 61018923f9a2e83675aecba7561f5095429fb467633Brian Salomon 61118923f9a2e83675aecba7561f5095429fb467633Brian Salomon uint32_t fRegenFlags = 0; 61218923f9a2e83675aecba7561f5095429fb467633Brian Salomon int fCurrGlyph = 0; 61318923f9a2e83675aecba7561f5095429fb467633Brian Salomon bool fBrokenRun = false; 61418923f9a2e83675aecba7561f5095429fb467633Brian Salomon}; 61518923f9a2e83675aecba7561f5095429fb467633Brian Salomon 616374b2f7cea8b1117f0dd17cdecd2b3ec85b141d4joshualitt#endif 617