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