OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrAtlasTextContext_DEFINED | 8 #ifndef GrAtlasTextContext_DEFINED |
9 #define GrAtlasTextContext_DEFINED | 9 #define GrAtlasTextContext_DEFINED |
10 | 10 |
11 #include "GrTextContext.h" | 11 #include "GrTextContext.h" |
12 | 12 |
13 #include "GrGeometryProcessor.h" | 13 #include "GrGeometryProcessor.h" |
14 #include "SkDescriptor.h" | 14 #include "SkDescriptor.h" |
| 15 #include "SkTextBlob.h" |
15 #include "SkTHash.h" | 16 #include "SkTHash.h" |
16 | 17 |
17 class GrBatchTextStrike; | 18 class GrBatchTextStrike; |
18 class GrPipelineBuilder; | 19 class GrPipelineBuilder; |
19 | 20 |
20 /* | 21 /* |
21 * This class implements GrTextContext using standard bitmap fonts, and can also
process textblobs. | 22 * This class implements GrTextContext using standard bitmap fonts, and can also
process textblobs. |
22 * TODO replace GrBitmapTextContext | 23 * TODO replace GrBitmapTextContext |
23 */ | 24 */ |
24 class GrAtlasTextContext : public GrTextContext { | 25 class GrAtlasTextContext : public GrTextContext { |
(...skipping 13 matching lines...) Expand all Loading... |
38 SkScalar x, SkScalar y, const SkIRect& regionClipBounds) ove
rride; | 39 SkScalar x, SkScalar y, const SkIRect& regionClipBounds) ove
rride; |
39 void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkP
aint&, | 40 void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkP
aint&, |
40 const SkMatrix& viewMatrix, | 41 const SkMatrix& viewMatrix, |
41 const char text[], size_t byteLength, | 42 const char text[], size_t byteLength, |
42 const SkScalar pos[], int scalarsPerPosition, | 43 const SkScalar pos[], int scalarsPerPosition, |
43 const SkPoint& offset, const SkIRect& regionClipBounds) o
verride; | 44 const SkPoint& offset, const SkIRect& regionClipBounds) o
verride; |
44 void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&, | 45 void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&, |
45 const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x,
SkScalar y, | 46 const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x,
SkScalar y, |
46 SkDrawFilter*, const SkIRect& clipBounds) override; | 47 SkDrawFilter*, const SkIRect& clipBounds) override; |
47 | 48 |
48 void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&, | |
49 const SkIRect& regionClipBounds); | |
50 | |
51 /* | 49 /* |
52 * A BitmapTextBlob contains a fully processed SkTextBlob, suitable for near
ly immediate drawing | 50 * A BitmapTextBlob contains a fully processed SkTextBlob, suitable for near
ly immediate drawing |
53 * on the GPU. These are initially created with valid positions and colors,
but invalid | 51 * on the GPU. These are initially created with valid positions and colors,
but invalid |
54 * texture coordinates. The BitmapTextBlob itself has a few Blob-wide prope
rties, and also | 52 * texture coordinates. The BitmapTextBlob itself has a few Blob-wide prope
rties, and also |
55 * consists of a number of runs. Runs inside a blob are flushed individuall
y so they can be | 53 * consists of a number of runs. Runs inside a blob are flushed individuall
y so they can be |
56 * reordered. | 54 * reordered. |
57 * | 55 * |
58 * The only thing(aside from a memcopy) required to flush a BitmapTextBlob i
s to ensure that | 56 * The only thing(aside from a memcopy) required to flush a BitmapTextBlob i
s to ensure that |
59 * the GrAtlas will not evict anything the Blob needs. | 57 * the GrAtlas will not evict anything the Blob needs. |
60 * TODO this is currently a bug | 58 * TODO this is currently a bug |
61 */ | 59 */ |
62 struct BitmapTextBlob : public SkRefCnt { | 60 struct BitmapTextBlob : public SkRefCnt { |
63 // Each Run inside of the blob can have its texture coordinates regenera
ted if required. | 61 /* |
64 // To determine if regeneration is necessary, fAtlasGeneration is used.
If there have been | 62 * Each Run inside of the blob can have its texture coordinates regenera
ted if required. |
65 // any evictions inside of the atlas, then we will simply regenerate Run
s. We could track | 63 * To determine if regeneration is necessary, fAtlasGeneration is used.
If there have been |
66 // this at a more fine grained level, but its not clear if this is worth
it, as evictions | 64 * any evictions inside of the atlas, then we will simply regenerate Run
s. We could track |
67 // should be fairly rare. | 65 * this at a more fine grained level, but its not clear if this is worth
it, as evictions |
68 // One additional point, each run can contain glyphs with any of the thr
ee mask formats. | 66 * should be fairly rare. |
69 // We call these SubRuns. Because a subrun must be a contiguous range,
we have to create | 67 * |
70 // a new subrun each time the mask format changes in a run. In theory,
a run can have as | 68 * One additional point, each run can contain glyphs with any of the thr
ee mask formats. |
71 // many SubRuns as it has glyphs, ie if a run alternates between color e
moji and A8. In | 69 * We call these SubRuns. Because a subrun must be a contiguous range,
we have to create |
72 // practice, the vast majority of runs have only a single subrun. | 70 * a new subrun each time the mask format changes in a run. In theory,
a run can have as |
| 71 * many SubRuns as it has glyphs, ie if a run alternates between color e
moji and A8. In |
| 72 * practice, the vast majority of runs have only a single subrun. |
| 73 * |
| 74 * Finally, for runs where the entire thing is too large for the GrAtlas
TextContext to |
| 75 * handle, we have a bit to mark the run as flusahable via rendering as
paths. It is worth |
| 76 * pointing. It would be a bit expensive to figure out ahead of time whe
ther or not a run |
| 77 * can flush in this manner, so we always allocate vertices for the run,
regardless of |
| 78 * whether or not it is too large. The benefit of this strategy is that
we can always reuse |
| 79 * a blob allocation regardless of viewmatrix changes. We could store p
ositions for these |
| 80 * glyphs. However, its not clear if this is a win because we'd still h
ave to either go the |
| 81 * glyph cache to get the path at flush time, or hold onto the path in t
he cache, which |
| 82 * would greatly increase the memory of these cached items. |
| 83 */ |
73 | 84 |
74 struct Run { | 85 struct Run { |
75 Run() : fColor(GrColor_ILLEGAL), fInitialized(false) { | 86 Run() : fColor(GrColor_ILLEGAL), fInitialized(false), fDrawAsPaths(f
alse) { |
76 fVertexBounds.setLargestInverted(); | 87 fVertexBounds.setLargestInverted(); |
77 // We insert the first subrun to gurantee a run always has atlea
st one subrun. | 88 // We insert the first subrun to gurantee a run always has atlea
st one subrun. |
78 // We do this to simplify things when we 'hand off' data from on
e subrun to the | 89 // We do this to simplify things when we 'hand off' data from on
e subrun to the |
79 // next | 90 // next |
80 fSubRunInfo.push_back(); | 91 fSubRunInfo.push_back(); |
81 } | 92 } |
82 struct SubRunInfo { | 93 struct SubRunInfo { |
83 SubRunInfo() | 94 SubRunInfo() |
84 : fAtlasGeneration(GrBatchAtlas::kInvalidAtlasGeneration) | 95 : fAtlasGeneration(GrBatchAtlas::kInvalidAtlasGeneration) |
85 , fGlyphStartIndex(0) | 96 , fGlyphStartIndex(0) |
86 , fGlyphEndIndex(0) | 97 , fGlyphEndIndex(0) |
87 , fVertexStartIndex(0) | 98 , fVertexStartIndex(0) |
88 , fVertexEndIndex(0) {} | 99 , fVertexEndIndex(0) {} |
89 GrMaskFormat fMaskFormat; | 100 GrMaskFormat fMaskFormat; |
90 uint64_t fAtlasGeneration; | 101 uint64_t fAtlasGeneration; |
91 uint32_t fGlyphStartIndex; | 102 uint32_t fGlyphStartIndex; |
92 uint32_t fGlyphEndIndex; | 103 uint32_t fGlyphEndIndex; |
93 size_t fVertexStartIndex; | 104 size_t fVertexStartIndex; |
94 size_t fVertexEndIndex; | 105 size_t fVertexEndIndex; |
95 }; | 106 }; |
96 SkSTArray<1, SubRunInfo, true> fSubRunInfo; | 107 SkSTArray<1, SubRunInfo, true> fSubRunInfo; |
97 SkAutoDescriptor fDescriptor; | 108 SkAutoDescriptor fDescriptor; |
98 SkAutoTUnref<SkTypeface> fTypeface; | 109 SkAutoTUnref<SkTypeface> fTypeface; |
99 SkRect fVertexBounds; | 110 SkRect fVertexBounds; |
100 GrColor fColor; | 111 GrColor fColor; |
101 bool fInitialized; | 112 bool fInitialized; |
| 113 bool fDrawAsPaths; |
102 }; | 114 }; |
103 | 115 |
104 struct BigGlyph { | 116 struct BigGlyph { |
105 BigGlyph(const SkPath& path, int vx, int vy) : fPath(path), fVx(vx),
fVy(vy) {} | 117 BigGlyph(const SkPath& path, int vx, int vy) : fPath(path), fVx(vx),
fVy(vy) {} |
106 SkPath fPath; | 118 SkPath fPath; |
107 int fVx; | 119 int fVx; |
108 int fVy; | 120 int fVy; |
109 }; | 121 }; |
110 | 122 |
111 SkTArray<BigGlyph> fBigGlyphs; | 123 SkTArray<BigGlyph> fBigGlyphs; |
112 SkMatrix fViewMatrix; | 124 SkMatrix fViewMatrix; |
113 SkScalar fX; | 125 SkScalar fX; |
114 SkScalar fY; | 126 SkScalar fY; |
115 SkPaint::Style fStyle; | 127 SkPaint::Style fStyle; |
116 uint32_t fRunCount; | 128 int fRunCount; |
117 | 129 |
118 // all glyph / vertex offsets are into these pools. | 130 // all glyph / vertex offsets are into these pools. |
119 unsigned char* fVertices; | 131 unsigned char* fVertices; |
120 GrGlyph::PackedID* fGlyphIDs; | 132 GrGlyph::PackedID* fGlyphIDs; |
121 Run* fRuns; | 133 Run* fRuns; |
122 | 134 |
123 static uint32_t Hash(const uint32_t& key) { | 135 static uint32_t Hash(const uint32_t& key) { |
124 return SkChecksum::Mix(key); | 136 return SkChecksum::Mix(key); |
125 } | 137 } |
126 | 138 |
127 void operator delete(void* p) { sk_free(p); } | 139 void operator delete(void* p) { sk_free(p); } |
128 void* operator new(size_t) { | 140 void* operator new(size_t) { |
129 SkFAIL("All blobs are created by placement new."); | 141 SkFAIL("All blobs are created by placement new."); |
130 return sk_malloc_throw(0); | 142 return sk_malloc_throw(0); |
131 } | 143 } |
132 | 144 |
133 void* operator new(size_t, void* p) { return p; } | 145 void* operator new(size_t, void* p) { return p; } |
134 void operator delete(void* target, void* placement) { | 146 void operator delete(void* target, void* placement) { |
135 ::operator delete(target, placement); | 147 ::operator delete(target, placement); |
136 } | 148 } |
137 }; | 149 }; |
138 | 150 |
139 typedef BitmapTextBlob::Run Run; | 151 typedef BitmapTextBlob::Run Run; |
140 typedef Run::SubRunInfo PerSubRunInfo; | 152 typedef Run::SubRunInfo PerSubRunInfo; |
141 | 153 |
142 BitmapTextBlob* CreateBlob(int glyphCount, int runCount); | 154 BitmapTextBlob* CreateBlob(int glyphCount, int runCount); |
143 | 155 |
144 void appendGlyph(BitmapTextBlob*, int runIndex, GrGlyph::PackedID, int left,
int top, | 156 void appendGlyph(BitmapTextBlob*, int runIndex, GrGlyph::PackedID, int left,
int top, |
145 GrColor color, GrFontScaler*, const SkIRect& clipRect); | 157 GrColor color, GrFontScaler*, const SkIRect& clipRect); |
146 void flush(GrDrawTarget*, BitmapTextBlob*, GrRenderTarget*, const GrPaint&,
const GrClip&, | 158 |
147 const SkMatrix& viewMatrix, int paintAlpha); | 159 inline void flushRunAsPaths(const SkTextBlob::RunIterator&, const SkPaint&,
SkDrawFilter*, |
| 160 const SkMatrix& viewMatrix, const SkIRect& clipB
ounds, SkScalar x, |
| 161 SkScalar y); |
| 162 inline void flushRun(GrDrawTarget*, GrPipelineBuilder*, BitmapTextBlob*, int
run, GrColor, |
| 163 uint8_t paintAlpha); |
| 164 inline void flushBigGlyphs(BitmapTextBlob* cacheBlob, GrRenderTarget* rt, |
| 165 const GrPaint& grPaint, const GrClip& clip); |
| 166 |
| 167 // We have to flush SkTextBlobs differently from drawText / drawPosText |
| 168 void flush(GrDrawTarget*, const SkTextBlob*, BitmapTextBlob*, GrRenderTarget
*, const SkPaint&, |
| 169 const GrPaint&, SkDrawFilter*, const GrClip&, const SkMatrix& vie
wMatrix, |
| 170 const SkIRect& clipBounds, SkScalar x, SkScalar y); |
| 171 void flush(GrDrawTarget*, BitmapTextBlob*, GrRenderTarget*, const SkPaint&, |
| 172 const GrPaint&, const GrClip&, const SkMatrix& viewMatrix); |
148 | 173 |
149 void internalDrawText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const Sk
Paint&, | 174 void internalDrawText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const Sk
Paint&, |
150 const SkMatrix& viewMatrix, const char text[], size_t
byteLength, | 175 const SkMatrix& viewMatrix, const char text[], size_t
byteLength, |
151 SkScalar x, SkScalar y, const SkIRect& clipRect); | 176 SkScalar x, SkScalar y, const SkIRect& clipRect); |
152 void internalDrawPosText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const
SkPaint&, | 177 void internalDrawPosText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const
SkPaint&, |
153 const SkMatrix& viewMatrix, | 178 const SkMatrix& viewMatrix, |
154 const char text[], size_t byteLength, | 179 const char text[], size_t byteLength, |
155 const SkScalar pos[], int scalarsPerPosition, | 180 const SkScalar pos[], int scalarsPerPosition, |
156 const SkPoint& offset, const SkIRect& clipRect); | 181 const SkPoint& offset, const SkIRect& clipRect); |
157 | 182 |
(...skipping 15 matching lines...) Expand all Loading... |
173 // TODO use real cache | 198 // TODO use real cache |
174 static void ClearCacheEntry(uint32_t key, BitmapTextBlob**); | 199 static void ClearCacheEntry(uint32_t key, BitmapTextBlob**); |
175 SkTHashMap<uint32_t, BitmapTextBlob*, BitmapTextBlob::Hash> fCache; | 200 SkTHashMap<uint32_t, BitmapTextBlob*, BitmapTextBlob::Hash> fCache; |
176 | 201 |
177 friend class BitmapTextBatch; | 202 friend class BitmapTextBatch; |
178 | 203 |
179 typedef GrTextContext INHERITED; | 204 typedef GrTextContext INHERITED; |
180 }; | 205 }; |
181 | 206 |
182 #endif | 207 #endif |
OLD | NEW |